-
Notifications
You must be signed in to change notification settings - Fork 113
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
Rawspeed: DngDecoder: add support for deflate decompression #17
Conversation
I wonder what the future policy wrt. external dependencies is? So far adding zlib was a no-go which is why we never added deflate support. Has that changed with us taking over? Or should we rather look for one of those minimalistic implementations that fit into a single file and can be bundled? |
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.
Looks, promising, i'm not against zlib as a dependency.
if (sample_format == 3 && bps != 32 && compression != 8) | ||
ThrowRDE("DNG Decoder: Float point must be 32 bits per sample."); | ||
|
||
// FIXME: We're creating USHORT16 image for all deflate images |
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.
That's not rawspeed's problem. Just provide non-normalized float image.
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 tried, darktable can't handle it - it displays it all white.
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 know.
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 handle the darktable-side patch)
@@ -81,9 +81,16 @@ RawImage DngDecoder::decodeRawInternal() { | |||
if (raw->hasEntry(SAMPLEFORMAT)) | |||
sample_format = raw->getEntry(SAMPLEFORMAT)->getInt(); | |||
|
|||
if (sample_format == 1) | |||
int compression = -1; | |||
compression = raw->getEntry(COMPRESSION)->getShort(); |
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.
And if there is no such tag?
} | ||
} | ||
|
||
// From DNG SDK dng_utils.h |
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.
And what is the legal status of such codedrop?
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.
From DNG SDK license agreement:
-
LICENSE GRANT
Software License. Subject to the restrictions below and other terms of this Agreement, Adobe hereby grants you a non-exclusive, worldwide, royalty free license to use, reproduce, prepare derivative works from, publicly display, publicly perform, distribute and sublicense the Software for any purpose. -
RESTRICTIONS AND OWNERSHIP
You will not remove any copyright or other notice included in the Software or Documentation and you will include such notices in any copies of the Software that you distribute in human-readable format.
I'll move it to another file and will add Adobe copyright note. Looks like RawTherapee violates Adobe license.
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.
Can such code even be used in LGPL library?
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.
Both RawTherapee and hdrmerge use parts of DNG SDK, but of course it's not an excuse for darktable. As far as I can tell, DNG SDK license doesn't contradict LGPL, but I'm not a lawyer, so I can't tell for sure.
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'd personally try really hard to find a better-licensed version of this function.
After all, it looks like it simply converts half-float to full float.
Probably OpenEXR has such a function.
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 agree. Will do.
while (!t->slices.empty()) { | ||
DngSliceElement e = t->slices.front(); | ||
if (!uBuffer) | ||
uBuffer = new unsigned char [e.width * e.height * sizeof(float)]; |
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.
Let's not take any chances and reorder it like: sizeof(float) * e.width * e.height
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.
Multiplication is commutative, what's the difference?
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.
At least in C, typeof(sizeof())
is size_t
, but are width
and height
of size_t
type too?
If not, the multiplication can somewhat easily overflow, i believe.
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.
Fair enough
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.
Fixed and pushed.
@@ -26,6 +26,9 @@ include_directories(SYSTEM ${Pugixml_INCLUDE_DIRS}) | |||
find_package(JPEG REQUIRED) | |||
include_directories(SYSTEM ${JPEG_INCLUDE_DIRS}) | |||
|
|||
find_package(ZLIB REQUIRED) |
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.
@houz is right. But now, it is up to me i guess.
I consider zlib to be ok as a dep. I may need to revisit this once i finally start to look at fuzzing, but for now it is ok.
What i do however think, is that it should be an option, i.e. it should be able to pass -DWITH_ZLIB=OFF
to cmake, and that code will not be compiled.
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.
OK
@@ -143,6 +143,159 @@ my_error_throw (j_common_ptr cinfo) | |||
ThrowRDE("JPEG decoder error!"); | |||
} | |||
|
|||
static void decodeFPDeltaRow(unsigned char * src, unsigned char * dst, size_t tileWidth, size_t realTileWidth, unsigned int bytesps, int factor) { |
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.
Where this is from?
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.
From RawTherapee, dcraw.cc, it's license says:
No license is required to download and use dcraw.c. However,
to lawfully redistribute dcraw, you must either (a) offer, at
no extra charge, full source code* for all executable files
containing RESTRICTED functions, (b) distribute this code under
the GPL Version 2 or later, (c) remove all RESTRICTED functions,
re-implement them, or copy them from an earlier, unrestricted
Revision of dcraw.c, or (d) purchase a license from the author.
I chose option (c), since these functions are not restricted.
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.
TBN, it is not from dcraw.c
https://github.com/Beep6581/RawTherapee/blob/880d0305486d8d9f6a4bb71c9f42a45921bfe48e/rtengine/dcraw.patch#L3173
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.
It's from dcraw.cc, not from dcraw.c
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.
jcelaya/hdrmerge#103 (comment)
So MIT License, copyright 2014 Javier Celaya <jcelaya@gmail.com>
Now, can it be used in with LGPL?
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.
Yes, it can be relicensed under LGPL, explanation is here:
http://softwareengineering.stackexchange.com/questions/105912/can-you-change-code-distributed-under-the-mit-license-and-re-distribute-it-unde
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 GPL and LGPL licenses are not synonyms, they are 2 different things, and i see nothing about LGPL on that page.
But yes, i do think that this MIT code can be used.
Do put MIT License, copyright 2014 Javier Celaya <jcelaya@gmail.com>
as comment before the function.
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.
Of course they are not. From the link above:
Note that the MIT license explicitly includes the right to sublicense. Quoting: "the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell"
When I sublicense code, I cannot grant rights that I didn't originally have. In the case of the GPL, I am explicitly forbidden to sublicense only some rights. But neither in law nor in the MIT license do I have an obligation to sublicense all rights as a whole.
LGPL is more permissive than GPL, i.e. you can sublicense more rights that you already have. So I see no problem in sublicensing the code under LGPL.
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.
OK.
decodeFPDeltaRow(src, (unsigned char *)floatBuffer, thisTileWidth, e.width, bytesps, predFactor); | ||
expandFloats((unsigned char *)floatBuffer, thisTileWidth, bytesps); | ||
unsigned short *dst = (unsigned short *)((unsigned char *)mRaw->getData() + ((e.offY + row) * mRaw->pitch + e.offX * sizeof(ushort16) * mRaw->getCpp())); | ||
// FIXME: convert float to ushort16, because darktable doesn't support non-normalized float32 images |
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.
Nope.
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.
OK
Current coverage is 5.61% (diff: 0.00%)@@ develop #17 diff @@
========================================
Files 111 111
Lines 9285 9400 +115
Methods 1276 1288 +12
Messages 0 0
Branches 1725 1744 +19
========================================
Hits 528 528
- Misses 8757 8872 +115
Partials 0 0
|
I rewrote fp-conversion functions from scratch and addressed all other comments, please review it again. |
Please note that I tested it only with float to ushort16 conversion patch. |
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.
Getting there :)
@@ -60,7 +60,7 @@ RawImage DngDecoder::decodeRawInternal() { | |||
try { | |||
isSubsampled = (*i)->getEntry(NEWSUBFILETYPE)->getInt() & 1; // bit 0 is on if image is subsampled | |||
} catch (TiffParserException) {} | |||
if ((compression != 7 && compression != 1 && compression != 0x884c) || isSubsampled) { // Erase if subsampled, or not JPEG or uncompressed | |||
if ((compression != 7 && compression != 8 && compression != 1 && compression != 0x884c) || isSubsampled) { // Erase if subsampled, or not deflated, JPEG or uncompressed |
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.
If without ZLIB, deflated should be erased.
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.
OK
@@ -230,17 +234,23 @@ RawImage DngDecoder::decodeRawInternal() { | |||
} catch (TiffParserException) { | |||
ThrowRDE("DNG Decoder: Unsupported format, uncompressed with no strips."); | |||
} | |||
} else if (compression == 7 || compression == 0x884c) { | |||
} else if (compression == 7 || compression == 8 || compression == 0x884c) { |
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.
If without ZLIB, deflated should be ignored.
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.
In my opinion that's meaningless, since it decoding will fail later, and all extra ifdefs make code readability worse, but OK.
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.
Hmm, now that i think the second time, for now just do https://github.com/darktable-org/rawspeed/pull/17/files/4f2bdbbf76cb8c23be314d0b76effafd397f206e#r95054866
@@ -143,6 +143,204 @@ my_error_throw (j_common_ptr cinfo) | |||
ThrowRDE("JPEG decoder error!"); | |||
} | |||
|
|||
#ifdef HAVE_ZLIB | |||
static void decodeFPDeltaRow(unsigned char * src, unsigned char * dst, size_t tileWidth, size_t realTileWidth, unsigned int bytesps, int factor) |
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.
no i mean, put the exact quote from author right before this function
it should be something like
// decodeFPDeltaRow(): MIT License, copyright 2014 Javier Celaya <jcelaya@gmail.com>
static void decodeFPDeltaRow(unsigned char * src, unsigned char * dst, size_t tileWidth, size_t realTileWidth, unsigned int bytesps, int factor)
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.
OK
} | ||
} | ||
|
||
static uint32_t fp16ToFloat(uint16_t fp16) |
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.
Awesome, no more adobe code with questionable license!
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.
Note that i did not actually check that the function is implemented correctly. One day this will get to have an unit-test...
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 checked that it returns the same value as Adobe's implementation for all possible fp16 and fp24 values. The only difference is handling +-inf and NaN, Adobe converts them to +-max and 0 respectively, my implementation leaves them as is.
Anyway, unit-testing this code is pretty useless: for normalized values it's just a matter of testing how well compiler translates shifts to machine code, and for non-normalized it's essentially means reimplementing part of these functions in a test. The question is who will watch the watchman^Wtest ;)
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.
Potentially having NAN's in input data will seriously hurt all the further algorithms that e.g. blur
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.
Handle it later in darktable? IIRC DNG 1.4 spec says nothing about clamping infinity or treating NaN as zero.
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.
Currently we simply assume that the [float] input is always ok, and only special-case the code inside the pipe that produces NAN's to not produce them.
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 don't see anything that handles NaN's for uncompressed data (compression == 1) in rawspeed.
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.
Good point :)
I don't remember any reports about raws with NAN's, let's hope it stays that way :)
@@ -107,6 +107,9 @@ extern "C" { | |||
#include <list> | |||
using namespace std; | |||
|
|||
// ZLIB | |||
#include <zlib.h> |
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.
#ifdef HAVE_ZLIB
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.
OK
@@ -25,6 +25,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) | |||
option(WITH_PTHREADS "Enable threading support through pthread. Highly recommended" ON) | |||
option(USE_XMLLINT "Run xmllint to test if data/cameras.xml is valid" ON) | |||
option(BUILD_TESTING "Build the testing tree." ON) | |||
option(WITH_ZLIB "Enable ZLIB support for DNG deflate support" ON) |
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.
While there, please move this new line to after first two option(WITH_
Just OCD :)
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.
OK
* upstream/develop: (78 commits) rstest: -c: do not recreate hashes if already exists rstest: unbreak: RawParser::getDecoder() takes CameraMetaData* CMake: ok, bad idea, don't link librawspeed_static into librawspeed_test Enable OpenMP for tools. Add rstest tool, from Axel Waggershauser. For regression testing. CMake: build identify tool only if BUILD_TOOLS is on Add zlib into dockerfile and msys2 deps. For #17 close another leak, this time in X3fDecoder, which does not decode any of the samples on r.p.u at the moment anyway. CMake: compiler-flags: ASAN: use -O1. Else it is too slow ammend c29c11c (again, overlooked one case, sigh...) fix 'harmless' off-by-one buffer read overflow in PanaBitpump that has always been there but could only be discovered with ASAN after switching from stack to heap allocated memory amend 92e2d9d fixing a off-by-one buffer overflow regression fixed regression introduced by commit 0894ef9 (simple reversion of older commit) make the `curve` lookup table in `NikonDecompressor` just as big as required Revert "Cr2Decoder::decodeRawInternal(): don't stack-allocate LJpegPlain" Revert "Rw2Decoder::decodeThreaded(): don't stack-allocate PanaBitpump()" Revert "NefDecoder::decodeRawInternal(): don't stack-allocate NikonDecompressor." Allocate 32k buffer inside PanaBitpump on heap instead of stack. Move buffer for lookup table creation from NikonDecompressor member to local variable (now similar to all other, equivalent use cases). Switching from stack to heap allocation to reduce stack size from 16k to 32 bytes. Allocate the (one) huge array of struct HuffmanTable on the heap instead of the stack. Stack size of LJpegDecompressor goes down from about 9k to 240. ...
All comments are addressed now. |
ThrowRDE("DNG Decoder: Only 16 bit unsigned data supported for compressed data."); | ||
if (compression == 8 && sample_format != 3) | ||
ThrowRDE("DNG Decoder: Only float format is supported for deflate-compressed data."); | ||
else if (compression != 8 && sample_format != 1) |
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.
But compression != 8
only says that it is not deflate compression, not that it is jpeg compression?
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.
We're in a branch for jpeg and deflate. What else it could be?
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.
Aha, okay
@@ -143,6 +143,204 @@ my_error_throw (j_common_ptr cinfo) | |||
ThrowRDE("JPEG decoder error!"); | |||
} | |||
|
|||
#ifdef HAVE_ZLIB | |||
// decodeFPDeltaRow(): MIT License, copyright 2014 Javier Celaya <jcelaya@gmail.com> |
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.
Finally :)
} | ||
} else { | ||
union X { unsigned int x; unsigned char c; }; | ||
if (((union X){1}).c) { |
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 suggest to use the existing getHostEndianness()
from Common.h instead of introducing a new way to determine the endianness.
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.
While i do understand that this is basically a vendordrop from rt/jcelaya, i have to agree, please use getHostEndianness()
here.
return (sign << 31) | (fp32_exponent << 23) | fp32_fraction; | ||
} | ||
|
||
static uint32_t fp24ToFloat(uint32_t fp24) |
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.
Question: have you tried if hinting your compiler to inline
this function helps him to actually to it? Removing a function call in the innermost loop might be worth it.
As a general comment regarding the used types ( Note: In my opinion, the chosen names suck and I will definitely suggest to rename them later. Maybe exactly to the C99 standard types used here, but maybe to something more concise (I like the type names in rust a lot). Anyway, having it all consistent is a value in itself. |
for (size_t col = 0; col < tileWidth; ++col) { | ||
for (size_t byte = 0; byte < bytesps; ++byte) | ||
dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian | ||
} |
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.
Mis-indented }
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.
it's actually the whole block of 4 lines that is misindented. same for the else
block. but: a general clang-format whitespace cleanup will follow later anyway, right? (but only after my infrastructure rework! :))
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.
And since this is just one commit, also please try to format your new functions properly.
Only these few new functions, not the whole file/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.
I think after this iteration i will look at the needed dt changes.
} | ||
} else { | ||
union X { unsigned int x; unsigned char c; }; | ||
if (((union X){1}).c) { |
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.
While i do understand that this is basically a vendordrop from rt/jcelaya, i have to agree, please use getHostEndianness()
here.
for (size_t col = 0; col < tileWidth; ++col) { | ||
for (size_t byte = 0; byte < bytesps; ++byte) | ||
dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian | ||
} |
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.
And since this is just one commit, also please try to format your new functions properly.
Only these few new functions, not the whole file/etc.
unsigned char * src = uBuffer + row * e.width * bytesps; | ||
unsigned char *dst = (unsigned char *)mRaw->getData() + ((e.offY + row) * mRaw->pitch + e.offX * sizeof(float) * mRaw->getCpp()); | ||
if (predFactor) | ||
decodeFPDeltaRow(src, dst, thisTileWidth, e.width, bytesps, predFactor); |
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.
As @axxel points, regardless of whether it actually helps or not, it would be best if these decodeFPDeltaRow()
, expandFP16()
, expandFP24()
, fp16ToFloat()
and fp24ToFloat()
and be marked with inline
keyword.
Actually, i'm afraid i have to agree here.
Please be a little more specific :) |
Oh, potential big misunderstanding! :-). The names in this PR seem totally fine to me. I was referring to the type names in Common.h, which I just suggested to use, even though I think they are 'sub-optimal' (to be more politically correct (sorry for the language before)). |
Another round. |
if (WITH_ZLIB) | ||
find_package(ZLIB REQUIRED) | ||
if(NOT ZLIB_FOUND) | ||
message(SEND_ERROR "Did not found ZLIB! Either make it find ZLIB, or pass -DWITH_ZLIB=OFF to disable ZLIB.") |
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.
Spelling fix suggestion:
"found" -> "find"
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.
Oops, copy-pasted from missing pthread error message. Fixed now.
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.
@anarsoul thanks!
Okay, i took a look.
With https://raw.pixls.us/getfile.php/771/raw/5G4A9394.CR2 converted to 32bit, 24bit and 16bit HDR dng, i get:
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (16b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (24b.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
[rawspeed] (32b-fp-w-predictor.dng) DNGDEcodeThread: Caught exception.
@@ -60,7 +60,11 @@ RawImage DngDecoder::decodeRawInternal() { | |||
try { | |||
isSubsampled = (*i)->getEntry(NEWSUBFILETYPE)->getInt() & 1; // bit 0 is on if image is subsampled | |||
} catch (TiffParserException) {} | |||
#ifdef WITH_ZLIB |
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.
2 issues here:
- it's
HAVE_ZLIB
- unreadable.
This should be
if (!(compression == 7 ||
#ifdef HAVE_ZLIB
compression == 8 ||
#endif
compression == 1 || compression != 0x884c) ||
isSubsampled) { // Erase if subsampled, or not deflated, JPEG or
// uncompressed
@@ -81,6 +85,12 @@ RawImage DngDecoder::decodeRawInternal() { | |||
if (raw->hasEntry(SAMPLEFORMAT)) | |||
sample_format = raw->getEntry(SAMPLEFORMAT)->getInt(); | |||
|
|||
int compression = -1; |
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.
Now that i actually look, we have already did int compression = (*i)->getEntry(COMPRESSION)->getShort();
before. So just do
const int compression = raw->getEntry(COMPRESSION)->getShort();;
Sorry for asking about this earlier.
Sorry, should have commented already:
That way you can actually test just the rawspeed changes, without darktable. Kinda sorta. |
Works fine for me with your file coverted either to 16, 24 or 32 bit: WARNING: Couldn't find cameras.xml in '/usr/local/share/darktable/rawspeed/cameras.xml' |
Rest is addressed. |
Hmm, indeed, the tool does not cause it, but if i update darktable's rawspeed submodule with these changes, and when darktable loads these dng, then these exceptions are in output. |
I have no exceptions with darktable either, but the whole image is white. I bet if I patch rawspeed to convert floats to uint16 it'll work. |
With that specific 5G4A9394.cr2 coverted to HDR?
I'm sure it will, but that is a separate problem. |
Yes, with this specific 5G4A9394.cr2 converted to DNG using hdrmerge. |
@anarsoul hmm. |
Yes, they load fine. Do you need a screencast as a proof? :) What compiler do you use to compile darktable? |
Debian sid, gcc6.
|
I'm using gcc-6.2.1 on Archlinux, let me try to recompile darktable with your cflags... |
Still works fine, here's console output:
|
And now it does not. Gremlins. |
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.
Ok, not counting the darktable part, which is TODO, this is good. rstest reports no regressions.
@anarsoul thank you!
@LebedevRI since you mentioned rstest: we'd need at least one of those DNGs in the test-set, even though they violate the "hasn't been modified in any way" rule. |
@axxel i know, but then they would be straight out of hdrmerge, completely generated by it. and that would be kinda-ok. |
…l mem alloc. ================================================================= ==9166==ERROR: LeakSanitizer: detected memory leaks Direct leak of 144000000 byte(s) in 24 object(s) allocated from: #0 0x716db0 in operator new[](unsigned long) (/home/lebedevri/rawspeed/build-Clang-SANITIZE/src/utilities/rstest/rstest+0x716db0) #1 0xaae8ec in rawspeed::VC5Decompressor::Array2D<short>::create(unsigned int, unsigned int) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/VC5Decompressor.cpp:92:21 darktable-org#2 0xaab67e in rawspeed::VC5Decompressor::decode(unsigned int, unsigned int) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/VC5Decompressor.cpp:637:26 darktable-org#3 0xa8dab5 in rawspeed::AbstractDngDecompressor::decompressThreaded(rawspeed::RawDecompressorThread const*) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:138:11 darktable-org#4 0x8f64d8 in rawspeed::RawDecompressorThread::start_routine(void*) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractParallelizedDecompressor.h:67:22 darktable-org#5 0x8f3989 in rawspeed::AbstractParallelizedDecompressor::decompressOne(unsigned int) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractParallelizedDecompressor.cpp:39:3 darktable-org#6 0x8f40a4 in rawspeed::AbstractParallelizedDecompressor::startThreading(unsigned int) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractParallelizedDecompressor.cpp:55:12 darktable-org#7 0xa86672 in rawspeed::AbstractDngDecompressor::decompress() const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:44:3 darktable-org#8 0x9c4873 in rawspeed::DngDecoder::decodeData(rawspeed::TiffIFD const*, unsigned int) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decoders/DngDecoder.cpp:333:10 darktable-org#9 0x9c7cc6 in rawspeed::DngDecoder::decodeRawInternal() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decoders/DngDecoder.cpp:415:3 darktable-org#10 0xc02508 in rawspeed::RawDecoder::decodeRaw() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decoders/RawDecoder.cpp:260:20 darktable-org#11 0x7251ee in rawspeed::rstest::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rawspeed::CameraMetaData const*, rawspeed::rstest::options const&) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/utilities/rstest/rstest.cpp:380:12 darktable-org#12 0x729552 in .omp_outlined._debug__ /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/utilities/rstest/rstest.cpp:544:17 darktable-org#13 0x72a5ce in .omp_outlined. /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/utilities/rstest/rstest.cpp:538:3 darktable-org#14 0x7f35f57d03c2 in __kmp_invoke_microtask (/usr/lib/x86_64-linux-gnu/libomp.so.5+0x883c2) darktable-org#15 0x7f35f5783929 in __kmp_fork_call (/usr/lib/x86_64-linux-gnu/libomp.so.5+0x3b929) darktable-org#16 0x7f35f5775570 in __kmpc_fork_call (/usr/lib/x86_64-linux-gnu/libomp.so.5+0x2d570) darktable-org#17 0x727ab5 in main /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/utilities/rstest/rstest.cpp:536:9 darktable-org#18 0x7f35f558ab16 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x22b16) SUMMARY: AddressSanitizer: 144000000 byte(s) leaked in 24 allocation(s). xargs: /home/lebedevri/rawspeed/build-Clang-SANITIZE/src/utilities/rstest/rstest: terminated by signal 6
../src/librawspeed/io/BitPumpJPEG.h:71:24: runtime error: implicit conversion from type 'int' of value -256 (32-bit, signed) to type 'unsigned long long' changed the value to 18446744073709551360 (64-bit, unsigned) #0 0x58250f in rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut>::fillCache(unsigned char const*) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/io/BitPumpJPEG.h:71:24 #1 0x581b6f in rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut>::fillSafe() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/io/BitStream.h:124:14 darktable-org#2 0x581551 in rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut>::fill(unsigned int) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/io/BitStream.h:143:7 darktable-org#3 0x580a14 in int rawspeed::HuffmanTableLUT::decode<rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut>, true>(rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut>&) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/HuffmanTableLUT.h:192:8 darktable-org#4 0x580083 in int rawspeed::HuffmanTableLUT::decodeNext<rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut> >(rawspeed::BitStream<rawspeed::JPEGBitPumpTag, rawspeed::BitStreamCacheRightInLeftOut>&) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/HuffmanTableLUT.h:178:12 darktable-org#5 0x635327 in void rawspeed::LJpegDecompressor::decodeN<2, false>()::'lambda'(int)::operator()(int) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/LJpegDecompressor.cpp:193:37 darktable-org#6 0x625e41 in rawspeed::unroll_loop_t<void rawspeed::LJpegDecompressor::decodeN<2, false>()::'lambda'(int), 2ul>::repeat(void rawspeed::LJpegDecompressor::decodeN<2, false>()::'lambda'(int) const&) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/common/Common.h:232:5 darktable-org#7 0x625e41 in void rawspeed::unroll_loop<2ul, void rawspeed::LJpegDecompressor::decodeN<2, false>()::'lambda'(int)>(void rawspeed::LJpegDecompressor::decodeN<2, false>()::'lambda'(int) const&) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/common/Common.h:246 darktable-org#8 0x625e41 in void rawspeed::LJpegDecompressor::decodeN<2, false>() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/LJpegDecompressor.cpp:192 darktable-org#9 0x620fb6 in rawspeed::LJpegDecompressor::decodeScan() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/LJpegDecompressor.cpp:119:7 darktable-org#10 0x589995 in rawspeed::AbstractLJpegDecompressor::parseSOS(rawspeed::ByteStream) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp:210:3 darktable-org#11 0x585e78 in rawspeed::AbstractLJpegDecompressor::decode() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractLJpegDecompressor.cpp:101:7 darktable-org#12 0x61f7f7 in rawspeed::LJpegDecompressor::decode(unsigned int, unsigned int, unsigned int, unsigned int, bool) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/LJpegDecompressor.cpp:80:30 darktable-org#13 0x5fe5db in rawspeed::AbstractDngDecompressor::decompressThreaded(rawspeed::RawDecompressorThread const*) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:103:11 darktable-org#14 0x557894 in rawspeed::RawDecompressorThread::start_routine(void*) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractParallelizedDecompressor.h:67:22 darktable-org#15 0x555cd2 in rawspeed::AbstractParallelizedDecompressor::decompressOne(unsigned int) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractParallelizedDecompressor.cpp:39:3 darktable-org#16 0x55621e in rawspeed::AbstractParallelizedDecompressor::startThreading(unsigned int) const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractParallelizedDecompressor.cpp:55:12 darktable-org#17 0x5fc37b in rawspeed::AbstractDngDecompressor::decompress() const /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decompressors/AbstractDngDecompressor.cpp:44:3 darktable-org#18 0x5b12ba in rawspeed::DngDecoder::decodeData(rawspeed::TiffIFD const*, unsigned int) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decoders/DngDecoder.cpp:333:10 darktable-org#19 0x5b3201 in rawspeed::DngDecoder::decodeRawInternal() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decoders/DngDecoder.cpp:415:3 darktable-org#20 0x6c072d in rawspeed::RawDecoder::decodeRaw() /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/librawspeed/decoders/RawDecoder.cpp:260:20 darktable-org#21 0x4c58a5 in rawspeed::rstest::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, rawspeed::CameraMetaData const*, rawspeed::rstest::options const&) /home/lebedevri/rawspeed/build-Clang-SANITIZE/../src/utilities/rstest/rstest.cpp:380:12
Tested with files generated by hdrmerge, with this change darktable is able to import them.