image_decode metadata
Does the image_decode component support metadata? I'm trying to enumerate the tree after decoding a jpeg and am just getting a single parent node. It'd be nice to be able to get at least the orientation if it's in the EXIF data.
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 16144
- Joined: Wed Dec 04, 2013 11:27 am
- Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.
Re: image_decode metadata
Yes, it is supported - I wrote that code about a decade ago!
I'll see if I can dig out the test code for it as the spec isn't terribly clear on exactly what you need to call.
I'll see if I can dig out the test code for it as the spec isn't terribly clear on exactly what you need to call.
Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Re: image_decode metadata
Haha, always fun when old code comes back to haunt you. The enumeration process seemed simple enough but will all things IL I'm imagining I'm in the wrong state or something. I'm running this function after decoding is complete with EOS on the output buffer but I haven't closed any ports or changed states yet. Here's the doc I'm following:
https://github.com/raspberrypi/firmware ... adata.html
And my demo code:
//use with nodeID OMX_ALL to start, not getting much data from jpegs (?)
void printChildNodes(uint32_t nodeID, OMX_HANDLETYPE handle)
{
int ret2;
OMX_CONFIG_CONTAINERNODECOUNTTYPE containerCount;
containerCount.nSize = sizeof(OMX_CONFIG_CONTAINERNODECOUNTTYPE);
containerCount.nVersion.nVersion = OMX_VERSION;
containerCount.nParentNodeID = nodeID;
ret2 = OMX_GetConfig(handle,OMX_IndexConfigContainerNodeCount,&containerCount);
if(ret2 != OMX_ErrorNone)
pis_logMessage(PIS_LOGLEVEL_ALL,"JPEG Decoder: meta3: %s\n", OMX_errString(ret2));
printf("Num nodes: %d\n",containerCount.nNumNodes);
OMX_CONFIG_METADATAITEMTYPE metadataItem;
OMX_CONFIG_CONTAINERNODEIDTYPE node;
for(int i = 0;i<containerCount.nNumNodes;i++){
node.nNodeIndex = i;
node.nParentNodeID = nodeID;
node.nSize = sizeof(OMX_CONFIG_CONTAINERNODEIDTYPE);
node.nVersion.nVersion = OMX_VERSION;
ret2 = OMX_GetConfig(handle,OMX_IndexConfigCounterNodeID,&node);
if(ret2 != OMX_ErrorNone)
pis_logMessage(PIS_LOGLEVEL_ALL,"JPEG Decoder: meta4: %s\n", OMX_errString(ret2));
printf("Node Name: %s\n",node.cNodeName);
if(node.bIsLeafType == OMX_TRUE){
metadataItem.eScopeMode = OMX_MetadataScopeNodeLevel;
metadataItem.eSearchMode = OMX_MetadataSearchItemByIndex;
metadataItem.nMetadataItemIndex = node.nNodeID;
metadataItem.nSize = sizeof(OMX_CONFIG_METADATAITEMTYPE);
metadataItem.nVersion.nVersion = OMX_VERSION;
ret2 = OMX_GetConfig(handle,OMX_IndexConfigMetadataItem,&metadataItem);
if(ret2 != OMX_ErrorNone)
pis_logMessage(PIS_LOGLEVEL_ALL,"JPEG Decoder: meta5: %s\n", OMX_errString(ret2));
printf("Metadata value: %s=%s\n",metadataItem.nKey, metadataItem.nValue);
}else{
printf("Printing children of: %d\n",node.nNodeID);
printChildNodes(node.nNodeID,handle);
}
}
}
Thanks for the help, appreciate any words of advice you might have.
https://github.com/raspberrypi/firmware ... adata.html
And my demo code:
//use with nodeID OMX_ALL to start, not getting much data from jpegs (?)
void printChildNodes(uint32_t nodeID, OMX_HANDLETYPE handle)
{
int ret2;
OMX_CONFIG_CONTAINERNODECOUNTTYPE containerCount;
containerCount.nSize = sizeof(OMX_CONFIG_CONTAINERNODECOUNTTYPE);
containerCount.nVersion.nVersion = OMX_VERSION;
containerCount.nParentNodeID = nodeID;
ret2 = OMX_GetConfig(handle,OMX_IndexConfigContainerNodeCount,&containerCount);
if(ret2 != OMX_ErrorNone)
pis_logMessage(PIS_LOGLEVEL_ALL,"JPEG Decoder: meta3: %s\n", OMX_errString(ret2));
printf("Num nodes: %d\n",containerCount.nNumNodes);
OMX_CONFIG_METADATAITEMTYPE metadataItem;
OMX_CONFIG_CONTAINERNODEIDTYPE node;
for(int i = 0;i<containerCount.nNumNodes;i++){
node.nNodeIndex = i;
node.nParentNodeID = nodeID;
node.nSize = sizeof(OMX_CONFIG_CONTAINERNODEIDTYPE);
node.nVersion.nVersion = OMX_VERSION;
ret2 = OMX_GetConfig(handle,OMX_IndexConfigCounterNodeID,&node);
if(ret2 != OMX_ErrorNone)
pis_logMessage(PIS_LOGLEVEL_ALL,"JPEG Decoder: meta4: %s\n", OMX_errString(ret2));
printf("Node Name: %s\n",node.cNodeName);
if(node.bIsLeafType == OMX_TRUE){
metadataItem.eScopeMode = OMX_MetadataScopeNodeLevel;
metadataItem.eSearchMode = OMX_MetadataSearchItemByIndex;
metadataItem.nMetadataItemIndex = node.nNodeID;
metadataItem.nSize = sizeof(OMX_CONFIG_METADATAITEMTYPE);
metadataItem.nVersion.nVersion = OMX_VERSION;
ret2 = OMX_GetConfig(handle,OMX_IndexConfigMetadataItem,&metadataItem);
if(ret2 != OMX_ErrorNone)
pis_logMessage(PIS_LOGLEVEL_ALL,"JPEG Decoder: meta5: %s\n", OMX_errString(ret2));
printf("Metadata value: %s=%s\n",metadataItem.nKey, metadataItem.nValue);
}else{
printf("Printing children of: %d\n",node.nNodeID);
printChildNodes(node.nNodeID,handle);
}
}
}
Thanks for the help, appreciate any words of advice you might have.
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 16144
- Joined: Wed Dec 04, 2013 11:27 am
- Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.
Re: image_decode metadata
Sorry, it's going to take a little time to dig out what is expected for metadata.
My implementation was for the old (deprecated) read_still and write_still components, which did all the file access as well as decode/encode stuff. I'm not sure how that has been carried across to image_decode and image_encode where the handling is based on buffers being passed in.
It'll be IFD0.Orientation that you're after for orientation. IIRC IFD0 vs IFD1 (main image vs thumbnail) was selected by setting the OMX_MetadataScopePortLevel and seelcting the appropriate stream with OMX_IndexParamActiveStream.
Is there any reason you can't use libexif or similar to read the info on the ARM? In the long run it's likely to be almost as quick and a lot less effort.
My implementation was for the old (deprecated) read_still and write_still components, which did all the file access as well as decode/encode stuff. I'm not sure how that has been carried across to image_decode and image_encode where the handling is based on buffers being passed in.
It'll be IFD0.Orientation that you're after for orientation. IIRC IFD0 vs IFD1 (main image vs thumbnail) was selected by setting the OMX_MetadataScopePortLevel and seelcting the appropriate stream with OMX_IndexParamActiveStream.
Is there any reason you can't use libexif or similar to read the info on the ARM? In the long run it's likely to be almost as quick and a lot less effort.
Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 16144
- Joined: Wed Dec 04, 2013 11:27 am
- Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.
Re: image_decode metadata
Ah, just noted in the image_decode source that at the same point it sends the EOS it calls a function called id_metadata_cleanup that will nuke the metadata structures.
It looks like you need to interrogate the metadata after sending the first buffer (80kB is guaranteed to include the full EXIF) and before sending the EOS/decoding the last stripe. That latter condition could be tricky on very small JPEGs that fit in < 80kB.
It looks like you need to interrogate the metadata after sending the first buffer (80kB is guaranteed to include the full EXIF) and before sending the EOS/decoding the last stripe. That latter condition could be tricky on very small JPEGs that fit in < 80kB.
Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Re: image_decode metadata
Ah, I'll have to play with the buffers and see what I can pull out. The input buffering seems to be a bit finicky though. I may just use that library, mostly I was playing with the idea while I contemplated/procrastinated some other parts of the code. Is the source for the components available somewhere? I don't mind digging out those types of idiosyncrasies myself but best as I can figure those sections are still behind a blob somewhere. Thanks again for the assist.