2121
2222#include " decompressors/LJpegDecompressor.h"
2323#include " adt/CroppedArray2DRef.h" // for CroppedArray2DRef
24- #include " adt/Point.h" // for iPoint2D
2524#include " common/Common.h" // for to_array, roundUpDivision
2625#include " common/RawImage.h" // for RawImage, RawImageData
2726#include " decoders/RawDecoderException.h" // for ThrowException, ThrowRDE
@@ -59,7 +58,7 @@ LJpegDecompressor::LJpegDecompressor(const ByteStream& bs, const RawImage& img)
5958
6059void LJpegDecompressor::decode (uint32_t offsetX, uint32_t offsetY,
6160 uint32_t width, uint32_t height,
62- bool fixDng16Bug_) {
61+ bool fixDng16Bug_, bool sonyArrange_ ) {
6362 if (offsetX >= static_cast <unsigned >(mRaw ->dim .x ))
6463 ThrowRDE (" X offset outside of image" );
6564 if (offsetY >= static_cast <unsigned >(mRaw ->dim .y ))
@@ -84,12 +83,12 @@ void LJpegDecompressor::decode(uint32_t offsetX, uint32_t offsetY,
8483 h = height;
8584
8685 fixDng16Bug = fixDng16Bug_;
86+ sonyArrange = sonyArrange_;
8787
8888 AbstractLJpegDecompressor::decode ();
8989}
9090
91- void LJpegDecompressor::decodeScan ()
92- {
91+ void LJpegDecompressor::decodeScan () {
9392 assert (frame.cps > 0 );
9493
9594 if (predictorMode != 1 )
@@ -104,14 +103,16 @@ void LJpegDecompressor::decodeScan()
104103 ThrowRDE (" Got less pixels than the components per sample" );
105104
106105 // How many output pixels are we expected to produce, as per DNG tiling?
107- const auto tileRequiredWidth = mRaw ->getCpp () * w;
106+ const auto tileRequiredWidth = mRaw ->getCpp () * w * (sonyArrange ? 2 : 1 );
107+ // How many of these rows do we need?
108+ const auto numRows = h / (sonyArrange ? 2 : 1 );
108109
109110 // How many full pixel blocks do we need to consume for that?
110111 if (const auto blocksToConsume =
111112 roundUpDivision (tileRequiredWidth, frame.cps );
112- frame.w < blocksToConsume || frame.h < h ) {
113+ frame.w < blocksToConsume || frame.h < numRows ) {
113114 ThrowRDE (" LJpeg frame (%u, %u) is smaller than expected (%u, %u)" ,
114- frame.cps * frame.w , frame.h , tileRequiredWidth, h );
115+ frame.cps * frame.w , frame.h , tileRequiredWidth, numRows );
115116 }
116117
117118 // How many full pixel blocks will we produce?
@@ -164,6 +165,7 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
164165 assert (N_COMP > 0 );
165166 assert (N_COMP >= mRaw ->getCpp ());
166167 assert ((N_COMP / mRaw ->getCpp ()) > 0 );
168+ assert (N_COMP == 4 || !sonyArrange);
167169
168170 assert (mRaw ->dim .x >= N_COMP);
169171 assert ((mRaw ->getCpp () * (mRaw ->dim .x - offX)) >= N_COMP);
@@ -188,22 +190,24 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
188190 assert (offY + h <= static_cast <unsigned >(mRaw ->dim .y ));
189191 assert (offX + w <= static_cast <unsigned >(mRaw ->dim .x ));
190192
193+ const auto numRows = h / (sonyArrange ? 2 : 1 );
194+
191195 // For y, we can simply stop decoding when we reached the border.
192- for (unsigned row = 0 ; row < h ; ++row) {
196+ for (unsigned row = 0 ; row < numRows ; ++row) {
193197 unsigned col = 0 ;
194198
195- copy_n (predNext, N_COMP, pred.data ());
196- // the predictor for the next line is the start of this line
197- predNext = &img (row, col);
198-
199199 // FIXME: predictor may have value outside of the uint16_t.
200200 // https://github.com/darktable-org/rawspeed/issues/175
201201
202202 // For x, we first process all full pixel blocks within the image buffer ...
203203 for (; col < N_COMP * fullBlocks; col += N_COMP) {
204204 for (int i = 0 ; i != N_COMP; ++i) {
205205 pred[i] = uint16_t (pred[i] + ht[i]->decodeDifference (bitStream));
206- img (row, col + i) = pred[i];
206+ if (sonyArrange) {
207+ img ((row * 2 ) + (i >> 1 ), (col / 2 ) + (i & 1 )) = pred[i];
208+ } else {
209+ img (row, col + i) = pred[i];
210+ }
207211 }
208212 }
209213
@@ -231,7 +235,15 @@ template <int N_COMP, bool WeirdWidth> void LJpegDecompressor::decodeN() {
231235
232236 // ... and discard the rest.
233237 for (; col < N_COMP * frame.w ; col += N_COMP) {
234- for (int i = 0 ; i != N_COMP; ++i) ht[i]->decodeDifference (bitStream);
238+ for (int i = 0 ; i != N_COMP; ++i)
239+ ht[i]->decodeDifference (bitStream);
240+ }
241+
242+ if (sonyArrange) {
243+ copy_n (&img (row * 2 , 0 ), 2 , pred.data ());
244+ copy_n (&img (row * 2 + 1 , 0 ), 2 , pred.data () + 2 );
245+ } else {
246+ copy_n (&img (row, 0 ), N_COMP, pred.data ());
235247 }
236248 }
237249}
0 commit comments