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

LJpegDecompressor predictor mode 6 support #189

Open
LebedevRI opened this issue Jun 30, 2019 · 11 comments
Open

LJpegDecompressor predictor mode 6 support #189

LebedevRI opened this issue Jun 30, 2019 · 11 comments

Comments

@LebedevRI
Copy link
Member

Comes up in Blackmagic cameras, Magic Lantern DNG's.

./Blackmagic/Pocket Cinema Camera/Blackmagic_Pocket_Cinema_Camera_1_2016-09-17_0053_C0022_000007.dng failed: ../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:208: void rawspeed::AbstractDngDecompressor::decompress() const: Too many errors encountered. Giving up. First Error:
../src/librawspeed/decompressors/LJpegDecompressor.cpp:88: virtual void rawspeed::LJpegDecompressor::decodeScan(): Unsupported predictor mode: 6
./Blackmagic/URSA 4K/Blackmagic URSA_1_1999-12-31_2153_C0003_000001.dng failed: ../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:208: void rawspeed::AbstractDngDecompressor::decompress() const: Too many errors encountered. Giving up. First Error:
../src/librawspeed/decompressors/LJpegDecompressor.cpp:88: virtual void rawspeed::LJpegDecompressor::decodeScan(): Unsupported predictor mode: 6
./Canon/EOS 5D Mark III/compress.dng failed: ../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:208: void rawspeed::AbstractDngDecompressor::decompress() const: Too many errors encountered. Giving up. First Error:
../src/librawspeed/decompressors/LJpegDecompressor.cpp:88: virtual void rawspeed::LJpegDecompressor::decodeScan(): Unsupported predictor mode: 6
./Canon/EOS 60D/M14-1451_000085_cDNG_compressed.dng failed: ../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:208: void rawspeed::AbstractDngDecompressor::decompress() const: Too many errors encountered. Giving up. First Error:
../src/librawspeed/decompressors/LJpegDecompressor.cpp:88: virtual void rawspeed::LJpegDecompressor::decodeScan(): Unsupported predictor mode: 6

@kmilos
Copy link
Collaborator

kmilos commented Dec 30, 2021

Even w/ the predictor implemented, there is still some way to go - seems to be the BlackMagick TIFF tile tags vs LJpeg SOF3 frame geometry is a bit wonky/unexpected compared to "normal" CFA lossless DNGs?

[rawspeed] (Blackmagic - URSA 4K - 12bit (16_9).dng) C:/msys64/home/kmilos/darktable/src/external/rawspeed/src/librawspeed/decompressors/AbstractDngDecompressor.cpp:217: void rawspeed::AbstractDngDecompressor::decompress() const: Too many errors encountered. Giving up. First Error:
C:/msys64/home/kmilos/darktable/src/external/rawspeed/src/librawspeed/decompressors/LJpegDecompressor.cpp:112: virtual void rawspeed::LJpegDecompressor::decodeScan(): LJpeg frame (1008, 1096) is smaller than expected (504, 2192)

@kmilos
Copy link
Collaborator

kmilos commented Jan 3, 2022

Yep, unlike Adobe's "normal" lossless mode that has an SOF3 w/ H x W/2 x 2ch and matching TIFF tiles of H x W after reshaping, the Blackmagic SOF3 in the URSA 4K really is FF D8 FF C3 00 0B 0C 04 48 03 F0 01 00 11 00, i.e. 1096 x 1008 x 1ch, while the TIFF tags are

Exif.Image.TileWidth                          504
Exif.Image.TileLength                         2192

Not sure which one of them is wrong and how to reshape, could be that it is H/2 x 2W x 1 -> H x W? In any case this test/assumption breaks.

@kmilos
Copy link
Collaborator

kmilos commented Jan 3, 2022

Did a quick test of manually changing the TIFF tags, and the results is not good (output image is sliced up incorrectly), so it really does seem the "special" reshaping needs to be done at the SOF3 decoding stage.

@LebedevRI LebedevRI moved this to Code needs porting in New Raw Formats Dec 19, 2022
@kmilos
Copy link
Collaborator

kmilos commented Jun 9, 2023

Yay, more Ljpeg fun - predictor 6 just popped up in DJI Mavic 3 Pro DNGs as well...

TileWidth                       : 4000
TileLength                      : 3000

w/

SOF3 (8000x1500): FF C3 00 0B 10 05 DC 1F 40 01 00 11 00
SOS: FF DA 00 08 01 00 00 06 00 00

Edit: This is the same 2W x H/2 scatter/gather as Blackmagic.

@kmilos
Copy link
Collaborator

kmilos commented Jun 17, 2023

While the Sony ARW case was somewhat straightforward (we know a priori how to reshape the TIFF tiles, decompress, and then deinterleave back because it is the sole ARW lossless mode), it is not so for these Blackmagic/DJI/MLV CinemaDNGs - the tiling in the DngDecoder is done before any LJpeg parsing, and there is no other way to tell one needs the tile reshaping and subsequent deinterleaving compared to "traditional" DNGs.

So the ideal flow after refactoring should be:

  1. Parse LJpeg SOF3 first to get frame.h, frame.w, and frame.cps
  2. Ensure that frame.cps * frame.w * frame.h == tilew * tileh (* spp?)
  3. DngDecoder reshapes tilew = frame.cps * frame.w (/spp?), tileh = frame.h
  4. Only then get DngTilingDescription
  5. Decompress
  6. Deinterleave if reshaped previously

Right now, the DNG tiling (coming first) and LJpeg parsing are completely independent.

@LebedevRI
Copy link
Member Author

Apologies if i have asked this before, but do we have example DNG's with predictor=0,
with such an LJpeg structure (that requires reshaping)?

@kmilos
Copy link
Collaborator

kmilos commented Jun 18, 2023

predictor=0 is not really valid/supported, did you mean 6? If so, then, yes, we do have several samples on RPU.

Please also note that I have updated the diagram - I now believe the reshaping and deinterleaving works out to be the same as the Sony case, despite the MCU difference.

@LebedevRI
Copy link
Member Author

predictor=0 is not really valid/supported, did you mean 6? If so, then, yes, we do have several samples on RPU.

Err, i meant whatever we currently already support, i.e. predictor=1.

@kmilos
Copy link
Collaborator

kmilos commented Jun 18, 2023

i meant whatever we currently already support, i.e. predictor=1

The known predictor=1 files (at least to me) are:

  • Adobe lossless DNGs (MCU has 2 components, and we already support tilew = 2 * frame.w "reshaping" so to speak)
  • various LinerRaw DNGs (trivial, as many components as color planes, no reshaping needed)
  • now Sony ARWs (MCU has 4 components, we reshape to tilew*2 x tileh/2, then deinterlace)

All others seem to require either predictor 6 or 7 supported AFAIK...

So, chicken and egg it would seem ;) As mentioned above - I have managed to decompress successfully w/ my "dumb" predictor patch (and by fudging the tiles in TIFF metadata manually), but the image comes out interlaced of course.

@kmilos
Copy link
Collaborator

kmilos commented Feb 26, 2024

@LebedevRI Note that the TIFF tile <-> JPEG SOF reshaping takes place for the lossy DNG mode as well, so ljpeg is probably not the place to address that in the abstraction hierarchy.

This is from the Blackmagic Pocket Cinema Camera 4K 3:1 lossy DNG:

TileWidth                       : 1032
TileLength                      : 2176

w/
SOF1 (lossy 2064x1088): FF C1 00 0B 0C 04 40 08 10 01 01 11 00
SOS: FF DA 00 08 01 01 00 00 3F 00

@kmilos
Copy link
Collaborator

kmilos commented Feb 27, 2024

Ah, turns out the reshaping for Blackmagic is even simpler than I thought: it's still 2W x H/2, but instead of flattening 2x2 pixel CFA macroblock into 4x1, it is just deinterleaving entire 2 rows, so one just needs to decode it into an appropriate buffer and it's done! I updated the diagram accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Code needs porting
Development

No branches or pull requests

2 participants