Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to read embedded png texture in FBX? (iOS/macOS) #1407

Closed
dmsurti opened this issue Aug 29, 2017 · 2 comments
Closed

How to read embedded png texture in FBX? (iOS/macOS) #1407

dmsurti opened this issue Aug 29, 2017 · 2 comments
Labels
Question Global flag to mark questions from users

Comments

@dmsurti
Copy link

dmsurti commented Aug 29, 2017

I am trying to read an embedded texture (png) in an FBX file. While I can correctly detect an embedded texture; I am not able to read texture->pcData. The relevant ObjC code:


               DLog(@" This is an embedded texture ");
               embeddedTexture = true;
                if(![[texFileName substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"*"]) {
                    return;
                }
               int k = [texFileName substringFromIndex:1].intValue;
               const struct aiTexture *texture = aiScene->mTextures[k];
                NSData *imageData = [NSData dataWithBytes:&texture->pcData length:texture->mWidth];
                
                uint8_t c;
                [imageData getBytes:&c length:1];
                
                switch ((c)) {
                    case 0x89:
                        DLog(@" This is a PNG");
                        break;
                        
                    default:
                        DLog(@" This is not a PNG");
                        break;
                }


When I run the above code, the output on console is:

2017-08-30 13:40:16.867287+0530 OSX-Example[7674:196288] -[AssimpImporter makeMaterialPropertyForMaterial:inScene:withTextureType:withSCNMaterial:atPath:] [Line 599]  has 1 textures
2017-08-30 13:40:16.867356+0530 OSX-Example[7674:196288] -[AssimpImporter makeMaterialPropertyForMaterial:inScene:withTextureType:withSCNMaterial:atPath:] [Line 612]  This is an embedded texture
2017-08-30 13:40:16.868097+0530 OSX-Example[7674:196288] -[AssimpImporter makeMaterialPropertyForMaterial:inScene:withTextureType:withSCNMaterial:atPath:] [Line 630]  This is not a PNG

As can be seen, the code detects from the raw data first byte, that it is not a PNG.

Is it me that is doing something wrong (hopefully, so :-) ? From the output however it seems the pcData is incorrect.

Is there any importer runtime setting or a build setting to ensure that pcData is populated correctly?

My system specs:

macOS: 10.12
Assimp lib: v4.0.1

@kimkulling kimkulling added the Question Global flag to mark questions from users label Aug 31, 2017
@dmsurti
Copy link
Author

dmsurti commented Sep 2, 2017

@kimkulling With the following changes in fbx loader related code:

  1. adding a uint_8 to hold raw image data in texture.h:
    uint8_t *rawImageData;
  1. Then reinterpret the pcData in FBXConverter.cpp as such:
   // steal the data from the Video to avoid an additional copy
    out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>( video ).RelinquishContent() );
    out_tex->rawImageData = reinterpret_cast< uint8_t *>(out_tex->pcData);

fixes the above problem. Without reinterpreting the pcData, in iOS/macOS I get invalid memory address for the memory buffer.

While this fix works, how correct/valid is it? I don't have FBX internals or Assimp internals knowledge in depth to judge; if you think this is valid, I could send a Pull Request with the fix.


With the above fix, generating an image object requires only the following:

    const struct aiTexture *aiTexture = aiScene->mTextures[index];
    NSData *imageData = [NSData dataWithBytes:aiTexture->pcData
                                       length:aiTexture->mWidth];
    self.imageDataProvider =
        CGDataProviderCreateWithCFData((CFDataRef)imageData);
    NSString* format = [NSString stringWithUTF8String:aiTexture->achFormatHint];
    if([format isEqualToString:@"png"]) {
        DLog(@" Created png embedded texture ");
        self.image = CGImageCreateWithPNGDataProvider(
            self.imageDataProvider, NULL, true, kCGRenderingIntentDefault);
    }
    if([format isEqualToString:@"jpg"]) {
        DLog(@" Created jpg embedded texture");
        self.image = CGImageCreateWithJPEGDataProvider(
            self.imageDataProvider, NULL, true, kCGRenderingIntentDefault);
    }

@kimkulling
Copy link
Member

There was a bug in the embeddded texture lookup, check: #1620

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question Global flag to mark questions from users
Projects
None yet
Development

No branches or pull requests

2 participants