-
Notifications
You must be signed in to change notification settings - Fork 121
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
First revision of Panasonic RW2 version 8 Decompressor #790
base: develop
Are you sure you want to change the base?
Conversation
Adapted from the Rust implementation in @cytrinox [dnglab](https://github.com/dnglab/dnglab). Should make it possible to provide support for several newer Panasonic cameras: G9M2, S5II, S1RII, GH6, GH7, and S9. In this branch, cameras.xml has only been updated for the G9M2.
@@ -71,7 +71,7 @@ BitStreamerReplenisherBase<Tag>::establishClassInvariants() const noexcept { | |||
} | |||
|
|||
template <typename Tag> | |||
struct BitStreamerForwardSequentialReplenisher final | |||
struct BitStreamerForwardSequentialReplenisher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to remove final
to implement BitStreamerReversedSequentialReplenisher
in PansonicV8Decompressor.cpp. See comments around that class for more context.
</ColorMatrix> | ||
</ColorMatrices> | ||
</Camera> | ||
<Camera make="Panasonic" model="DC-G9M2" mode="4:3"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More work on crop modes probably needs to be done. RW2 V8 cameras don't seem to crop into raw images the way the old Panasonic cameras did.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, only the older ones seem to actually crop the raw... I'm hoping it'll work out the same as v7, so I just have the "native" sensor crop/aspect in cameras.xml for now. (We never supported the "soft" crop anyway...)
I should be able to help w/ testing this a bit later. We'll need check any other non-standard modes though like high-res etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are your concerns w.r.t high-res mode? I've tested on plenty of high-res shots and not seen any apparent issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are your concerns w.r.t high-res mode?
Typically if we have a manual crop value other than (0,0,0,0) in cameras.xml for native mode it might not apply (i.e. crop too much or too little) in high-res mode for some other brands or codec (i.e. sensor and processor) versions... It'll just have to be checked out, that's all... Same for any other sensor readout modes like burst, live composite, multi-exposure etc. (present in earlier models like the S5, don't know if they are also in newer ones).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My (very) cursory crop tests so far, using LibRaw's unprocessed_raw
dumps for "native" mode samples only:
GH6: (0,0,0,0)
S5M2: (0,0,0,0)
S5M2X: (0,0,0,0)
G9M2: (0,0,0,0)
S9: (0,0,0,0)
GH7: (0,0,0,0)
S1RM2: (0,0,0,0)
These are w.r.t. sizes in e.g. these tags as reported by exiftool -a -u -s -G1 -H
:
[IFD0] 0x0002 SensorWidth
[IFD0] 0x0003 SensorHeight
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, if you're excluding the <Crop x="0" y="0" width="0" height="0"/>
like you have here, one should be getting the crop from vendor metadata tags (0x0004 SensorTopBorder
, 0x0005 SensorLeftBorder
, 0x0006 SensorBottomBorder
, 0x0007 SensorRightBorder
), so somewhat smaller than the full sensor...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not sure I'm following you, but happy to make any code changes needed.
Is this not covered by Are you suggesting that a further crop, on top of the sensor crop, may be necessary for files produced by the other modes?Rw2Decoder::getDefaultCrop()
? That seems to be checking the appropriate tags.
Edit: On second look, Rw2Decoder::getDefaultCrop()
doesn't seem to be called anywhere. Calling mRaw->subFrame(getDefaultCrop());
before returning the raw from Rw2Decoder::decodeRawInternal()
seems to correctly apply the crop. @kmilos Would you like me to push this change, or did you have something else in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This basically boils down to the choice between the vendor crop from metadata, or manual crop values from cameras.xml. Traditionally RawSpeed had a design goal mentioned on the landing page: "RawSpeed does NOT crop the image to the same sizes as manufactures, but supplies biggest possible images." This was foregone for some vendors/models, as it was becoming unwieldy to check, list and handle explicitly all possible modes via cameras.xml.
For the time being, I suggest to implement it like in the v5/v6 decoder: only call getDefaultCrop()
if <Crop/>
was not present and restore <Crop x="0" y="0" width="0" height="0"/>
in cameras.xml v8 model entries as those seem to be "well behaved" so far...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see. I can add that. Using zero crop on the images I've looked at does reveal some smeary pixels at the edges of the frame. I don't think it is an issue, but want to point it out in-case that biggest image design sentiment has changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add that.
Great!
Using zero crop on the images I've looked at does reveal some smeary pixels at the edges of the frame.
Let's check it out more closely for all models during this review and then either adjust the manual <Crop/>
accordingly, or simply drop it for some/all v8 finally.
CURRENTPREPROFILEMATRIX = 50834, | ||
COLORIMETRICREFERENCE = 50879, | ||
KODAKKDCPRIVATEIFD = 65024, | ||
SHADOWSCALE = 0XC633, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making use of hex values consistent for the enum, and grouped Panasonic tags together with the new ones. Hopefully not overstepping.
// The set of templates and classes below define a specialized bit streamer which works mostly the same as | ||
// BitStreamerMSB, but which reverses the ordering of the bits within each byte. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Panasonic files require streaming bits in a way which seems unsupported by the existing utilities. The bit-stream consumes bytes in MSB order, but reads the bits within each byte starting from the least-significant bits. Likewise a version of BitStreamerMSB
is needed which reverses bit order while caching bits from bytes. This is what I've done below, hacking together a BitStreamerReversedSequentialReplenisher
struct which is the same as BitStreamerForwardSequentialReplenisher
but which copies reversed bits within getInput()
I'm not at all happy with this solution, but it is the only solution I could come up with that didn't require writing a new bit pump implementation from scratch or radically changing existing bit streamer code.
In my opinion, the templating of the bit streaming classes make them very difficult to extend or modify without writing lots of new code. This is the briefest thing I could come up with, and it still feels over-verbose. I would greatly appreciate any recommendations on how to better handle this.
} | ||
|
||
/// Maybe the most complicated part of the entire file format, and seemingly, completely unused. | ||
void PanasonicV8Decompressor::populateGammaLUT(const TiffIFD& ifd) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in this function looks radically different from what is in the original implementation because I've done my best to reverse engineer the original intent, and to reduce it down into something shorter and more intelligible.
I'm fairly confident that this version is logically equivalent to the original, but since no RW2 file has ever been found which actually uses this code, it is difficult to know for sure. Caution should be taken if this code ever ends up in use.
I had missed these because I have been building the library through Darktable.
@@ -170,6 +171,16 @@ RawImage Rw2Decoder::decodeRawInternal() { | |||
v7.decompress(); | |||
return mRaw; | |||
} | |||
case 8: { | |||
// Most use bps=16, S9 uses bps=12 | |||
if (bitsPerSample != 16 && bitsPerSample != 12) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll probably remove this check. The BPS for V8 files seems to vary a lot, but should all decode fine.
e204089
to
3c87e16
Compare
* upstream/develop: .. but that directory isn't actually empty, it just doesn't have files CI: skip step if no clang-tidy YAML reports CI: run CodeQL static analysis even if some steps failed CI: disable `-Werror` for static analysis jobs Github: sarif-ify clang-tidy output CMake: add `RAWSPEED_ENABLE_CLANG_TIDY_WERROR` option Explicitly opt-out of `alpha.unix.Stream` CSA check rstest: add (some) missing checks that writing succeeded `FileReader::readFile()`: first check for erorr, then eof Upload CodeChecker results as SARIF Switch RPU masterset fetching to wget Add Nikon Z5_2 placeholder
Adapted from the Rust implementation in @cytrinox's dnglab. Should make it possible to provide support for several newer Panasonic cameras: G9M2, S5II, S1RII, GH6, GH7, and S9.
In this branch, cameras.xml has only been updated for the G9M2.