I have been doing some comparison of the size data (i.e., libraw_image_sizes_t struct) that LibRaw reads vs how Adobe interprets raw images (by using the DNG converter and reading the tags - same data as in Lightroom/Photoshop). Reason is that I'm working on a DNG-converter using LibRaw and would like the results to be as close to Adobe's version as possible (rightly or wrongly).
LibRaw effectively supplies
- the full sensor size (raw_height/width)
- the active area (top/left_margin, height/width)
[ plus the final size (iheight/iwidth) - in my sample always identical to height/width even with pixel_aspect != 1]
DNG effectively supplies
- the full sensor size (TIFF-tags imageHeight/Width)
- the active area (DNG-tag ActiveArea)
- the default crop (DefaultCropOrigin/Size) - [further crop within the active area to allow for interpolation at the edges]
[further data like DefaultScale (=pixel_aspect), DefaultUserCrop, ...]
I have compared these data sets over the ca. 260 different raw-samples from rawsamples.ch (further ~40 can only be read by LibRaw but not Adobe). I have attached the results (as formated if slightly dense PDF) and posted the raw data here (green/red signifies match/difference between LibRaw/Adobe).
While there are lots of matches, there is also quite a number of differences both in raw-size (surprisingly) and in the ActiveArea. And then LibRaw doesn't supply data for the DefaultCrop.
--> Is there a reason for the differences in ActiveArea? Is one of them right/wrong or is it interpretation? Is there additional data in LibRaw that would allow me to reconcile the differences?
--> Where does Adobe take the crop-data from? Can I get that data out of LibRaw? Or are they using an external data-set? If so, any idea where Adobe gets it from (i.e., where it is saved in the default installation if not in the binary) - it's not in the DCP-files, which only seem to contain the color-data...
Any insights appreciated, many thanks!
Unfortunately, there is no
Unfortunately, there is no any 'system' in LibRaw margin (ActiveArea) size.
- some of values are derived from dcraw without change
- some of values are read from RAW metadata
- some of values are assigned by hand with 'maximum possible area' in mind.
For entire sensor size, Adobe DNG convertor crops sensor data for some cameras for unknown reason. Also, this cropping may change with DNG convertor version change (I've seen this at least on some Fuji cameras).
Sensor size is definitely right in LibRaw. Wrong raw_width will result in completely distorted image, wrong (too small) raw_height will result in buffer overrun.
-- Alex Tutubalin @LibRaw LLC
Thank you, that's very
Thank you, that's very helpful. I'll go with LibRaw's sensor-size and ActiveArea then.
I actually care mostly about the DefaultCrop since that's what the users sees. I guess Adobe reads the final size from the MakerNotes (e.g., Sony has a FullImageSize tag) and then probably centers it in the ActiveArea. Will see if I can extract some of those with libexiv2.
To make it more complicated, there are also ImageWidth/Height Exif tags at least for Canon/Sony, which seem to also include user settings like 16:9 crop. Adobe (in DNG 1.4) interestingly translates that to DefaultUserCrop, which means the DNG includes 4 nested crops (sensor size, active area, default crop, default user crop)...
LibRaw do not care about in
LibRaw do not care about in-camera crops like 16:9 and always returns full image.
So, if you want to completely repeat Adobe DNG convertor behavior, you need to parse Exif/makernotes metadata (and, possibly, add vendor-specific or camera-specific hints).
AFAIK, Adobe default cropping is because of
- let some space for demosaic (so ignore pixels very close to border)
- let some space for sensor positioning errors (seen in some cameras, within several pixels)
- also, physical masking may produce border effects (like diffraction) close to mask edge.
-- Alex Tutubalin @LibRaw LLC
Adding support for crops?
I know they can be vendor specific but I wondered if you would take patches for decoding such information?
For example to get access to the Canon data, parse_makernote() would need code around line 8686 something like:
else if (tag == 0x0098) // CropInfo
unsigned short CropLeft = get2();
unsigned short CropRight = get2();
unsigned short CropTop = get2();
unsigned short CropBottom = get2();
fprintf (stderr, " Cropinfo %d %d %d %d\n", CropLeft, CropRight, CropTop, CropBottom);
else if (tag == 0x009a) // AspectInfo
unsigned int ratio = get4();
unsigned int CroppedWidth = get4();
unsigned int CroppedHeight = get4();
unsigned int CropLeft = get4();
unsigned int CropTop = get4();
fprintf (stderr, " AspectInfo %d %d %d %d %d\n", ratio, CroppedWidth, CroppedHeight,
Obviously this would need storing somewhere useful rather than simply printing it out, but that could then be passed back to the real crop functionality