1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "ImageLogging.h"  // Must appear first.
8 
9 #include "nsJPEGDecoder.h"
10 
11 #include <cstdint>
12 
13 #include "imgFrame.h"
14 #include "Orientation.h"
15 #include "EXIF.h"
16 
17 #include "nsIInputStream.h"
18 
19 #include "nspr.h"
20 #include "nsCRT.h"
21 #include "gfxColor.h"
22 
23 #include "jerror.h"
24 
25 #include "gfxPlatform.h"
26 #include "mozilla/EndianUtils.h"
27 #include "mozilla/Telemetry.h"
28 
29 extern "C" {
30 #include "iccjpeg.h"
31 
32 #ifdef JCS_EXTENSIONS
33 #if MOZ_BIG_ENDIAN
34 #define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_XRGB
35 #else
36 #define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_BGRX
37 #endif
38 #else
39 /* Colorspace conversion (copied from jpegint.h) */
40 struct jpeg_color_deconverter {
41   JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
42   JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
43 				JSAMPIMAGE input_buf, JDIMENSION input_row,
44 				JSAMPARRAY output_buf, int num_rows));
45 };
46 
47 METHODDEF(void)
48 ycc_rgb_convert_argb (j_decompress_ptr cinfo,
49                  JSAMPIMAGE input_buf, JDIMENSION input_row,
50                  JSAMPARRAY output_buf, int num_rows);
51 #endif
52 }
53 
54 static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width);
55 
56 namespace mozilla {
57 namespace image {
58 
59 static mozilla::LazyLogModule sJPEGLog("JPEGDecoder");
60 
61 static mozilla::LazyLogModule sJPEGDecoderAccountingLog("JPEGDecoderAccounting");
62 
63 static qcms_profile*
GetICCProfile(struct jpeg_decompress_struct & info)64 GetICCProfile(struct jpeg_decompress_struct& info)
65 {
66   JOCTET* profilebuf;
67   uint32_t profileLength;
68   qcms_profile* profile = nullptr;
69 
70   if (read_icc_profile(&info, &profilebuf, &profileLength)) {
71     profile = qcms_profile_from_memory(profilebuf, profileLength);
72     free(profilebuf);
73   }
74 
75   return profile;
76 }
77 
78 METHODDEF(void) init_source (j_decompress_ptr jd);
79 METHODDEF(boolean) fill_input_buffer (j_decompress_ptr jd);
80 METHODDEF(void) skip_input_data (j_decompress_ptr jd, long num_bytes);
81 METHODDEF(void) term_source (j_decompress_ptr jd);
82 METHODDEF(void) my_error_exit (j_common_ptr cinfo);
83 
84 // Normal JFIF markers can't have more bytes than this.
85 #define MAX_JPEG_MARKER_LENGTH  (((uint32_t)1 << 16) - 1)
86 
nsJPEGDecoder(RasterImage * aImage,Decoder::DecodeStyle aDecodeStyle)87 nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
88                              Decoder::DecodeStyle aDecodeStyle)
89  : Decoder(aImage)
90  , mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
91                                    State::JPEG_DATA,
92                                    SIZE_MAX),
93           Transition::TerminateSuccess())
94  , mDecodeStyle(aDecodeStyle)
95  , mSampleSize(0)
96 {
97   mState = JPEG_HEADER;
98   mReading = true;
99   mImageData = nullptr;
100 
101   mBytesToSkip = 0;
102   memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
103   memset(&mSourceMgr, 0, sizeof(mSourceMgr));
104   mInfo.client_data = (void*)this;
105 
106   mSegment = nullptr;
107   mSegmentLen = 0;
108 
109   mBackBuffer = nullptr;
110   mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0;
111 
112   mInProfile = nullptr;
113   mTransform = nullptr;
114 
115   mCMSMode = 0;
116 
117   MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
118          ("nsJPEGDecoder::nsJPEGDecoder: Creating JPEG decoder %p",
119           this));
120 }
121 
~nsJPEGDecoder()122 nsJPEGDecoder::~nsJPEGDecoder()
123 {
124   // Step 8: Release JPEG decompression object
125   mInfo.src = nullptr;
126   jpeg_destroy_decompress(&mInfo);
127 
128   PR_FREEIF(mBackBuffer);
129   if (mTransform) {
130     qcms_transform_release(mTransform);
131   }
132   if (mInProfile) {
133     qcms_profile_release(mInProfile);
134   }
135 
136   MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
137          ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p",
138           this));
139 }
140 
141 Maybe<Telemetry::ID>
SpeedHistogram() const142 nsJPEGDecoder::SpeedHistogram() const
143 {
144   return Some(Telemetry::IMAGE_DECODE_SPEED_JPEG);
145 }
146 
147 nsresult
InitInternal()148 nsJPEGDecoder::InitInternal()
149 {
150   mCMSMode = gfxPlatform::GetCMSMode();
151   if (GetSurfaceFlags() & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
152     mCMSMode = eCMSMode_Off;
153   }
154 
155   // We set up the normal JPEG error routines, then override error_exit.
156   mInfo.err = jpeg_std_error(&mErr.pub);
157   //   mInfo.err = jpeg_std_error(&mErr.pub);
158   mErr.pub.error_exit = my_error_exit;
159   // Establish the setjmp return context for my_error_exit to use.
160   if (setjmp(mErr.setjmp_buffer)) {
161     // If we get here, the JPEG code has signaled an error, and initialization
162     // has failed.
163     return NS_ERROR_FAILURE;
164   }
165 
166   // Step 1: allocate and initialize JPEG decompression object
167   jpeg_create_decompress(&mInfo);
168   // Set the source manager
169   mInfo.src = &mSourceMgr;
170 
171   // Step 2: specify data source (eg, a file)
172 
173   // Setup callback functions.
174   mSourceMgr.init_source = init_source;
175   mSourceMgr.fill_input_buffer = fill_input_buffer;
176   mSourceMgr.skip_input_data = skip_input_data;
177   mSourceMgr.resync_to_restart = jpeg_resync_to_restart;
178   mSourceMgr.term_source = term_source;
179 
180   // Record app markers for ICC data
181   for (uint32_t m = 0; m < 16; m++) {
182     jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF);
183   }
184 
185   return NS_OK;
186 }
187 
188 nsresult
FinishInternal()189 nsJPEGDecoder::FinishInternal()
190 {
191   // If we're not in any sort of error case, force our state to JPEG_DONE.
192   if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
193       (mState != JPEG_ERROR) &&
194       !IsMetadataDecode()) {
195     mState = JPEG_DONE;
196   }
197 
198   return NS_OK;
199 }
200 
201 LexerResult
DoDecode(SourceBufferIterator & aIterator,IResumable * aOnResume)202 nsJPEGDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
203 {
204   MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
205 
206   return mLexer.Lex(aIterator, aOnResume,
207                     [=](State aState, const char* aData, size_t aLength) {
208     switch (aState) {
209       case State::JPEG_DATA:
210         return ReadJPEGData(aData, aLength);
211       case State::FINISHED_JPEG_DATA:
212         return FinishedJPEGData();
213     }
214     MOZ_CRASH("Unknown State");
215   });
216 }
217 
218 LexerTransition<nsJPEGDecoder::State>
ReadJPEGData(const char * aData,size_t aLength)219 nsJPEGDecoder::ReadJPEGData(const char* aData, size_t aLength)
220 {
221   mSegment = reinterpret_cast<const JOCTET*>(aData);
222   mSegmentLen = aLength;
223 
224   // Return here if there is a fatal error within libjpeg.
225   nsresult error_code;
226   // This cast to nsresult makes sense because setjmp() returns whatever we
227   // passed to longjmp(), which was actually an nsresult.
228   if ((error_code = static_cast<nsresult>(setjmp(mErr.setjmp_buffer))) != NS_OK) {
229     if (error_code == NS_ERROR_FAILURE) {
230       // Error due to corrupt data. Make sure that we don't feed any more data
231       // to libjpeg-turbo.
232       mState = JPEG_SINK_NON_JPEG_TRAILER;
233       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
234              ("} (setjmp returned NS_ERROR_FAILURE)"));
235     } else {
236       // Error for another reason. (Possibly OOM.)
237       mState = JPEG_ERROR;
238       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
239              ("} (setjmp returned an error)"));
240     }
241 
242     return Transition::TerminateFailure();
243   }
244 
245   MOZ_LOG(sJPEGLog, LogLevel::Debug,
246          ("[this=%p] nsJPEGDecoder::Write -- processing JPEG data\n", this));
247 
248   switch (mState) {
249     case JPEG_HEADER: {
250       LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::Write -- entering JPEG_HEADER"
251                 " case");
252 
253       // Step 3: read file parameters with jpeg_read_header()
254       if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) {
255         MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
256                ("} (JPEG_SUSPENDED)"));
257         return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
258       }
259 
260       // If we have a sample size specified for -moz-sample-size, use it.
261       if (mSampleSize > 0) {
262         mInfo.scale_num = 1;
263         mInfo.scale_denom = mSampleSize;
264       }
265 
266       // Used to set up image size so arrays can be allocated
267       jpeg_calc_output_dimensions(&mInfo);
268 
269       // Post our size to the superclass
270       PostSize(mInfo.output_width, mInfo.output_height,
271                ReadOrientationFromEXIF());
272       if (HasError()) {
273         // Setting the size led to an error.
274         mState = JPEG_ERROR;
275         return Transition::TerminateFailure();
276       }
277 
278       // If we're doing a metadata decode, we're done.
279       if (IsMetadataDecode()) {
280         return Transition::TerminateSuccess();
281       }
282 
283       // We're doing a full decode.
284       if (mCMSMode != eCMSMode_Off &&
285           (mInProfile = GetICCProfile(mInfo)) != nullptr) {
286         uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
287         bool mismatch = false;
288 
289 #ifdef DEBUG_tor
290       fprintf(stderr, "JPEG profileSpace: 0x%08X\n", profileSpace);
291 #endif
292       switch (mInfo.jpeg_color_space) {
293         case JCS_GRAYSCALE:
294           if (profileSpace == icSigRgbData) {
295             mInfo.out_color_space = JCS_RGB;
296           } else if (profileSpace != icSigGrayData) {
297             mismatch = true;
298           }
299           break;
300         case JCS_RGB:
301           if (profileSpace != icSigRgbData) {
302             mismatch =  true;
303           }
304           break;
305         case JCS_YCbCr:
306           if (profileSpace == icSigRgbData) {
307             mInfo.out_color_space = JCS_RGB;
308           } else {
309             // qcms doesn't support ycbcr
310             mismatch = true;
311           }
312           break;
313         case JCS_CMYK:
314         case JCS_YCCK:
315             // qcms doesn't support cmyk
316             mismatch = true;
317           break;
318         default:
319           mState = JPEG_ERROR;
320           MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
321                  ("} (unknown colorpsace (1))"));
322           return Transition::TerminateFailure();
323       }
324 
325       if (!mismatch) {
326         qcms_data_type type;
327         switch (mInfo.out_color_space) {
328           case JCS_GRAYSCALE:
329             type = QCMS_DATA_GRAY_8;
330             break;
331           case JCS_RGB:
332             type = QCMS_DATA_RGB_8;
333             break;
334           default:
335             mState = JPEG_ERROR;
336             MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
337                    ("} (unknown colorpsace (2))"));
338             return Transition::TerminateFailure();
339         }
340 #if 0
341         // We don't currently support CMYK profiles. The following
342         // code dealt with lcms types. Add something like this
343         // back when we gain support for CMYK.
344 
345         // Adobe Photoshop writes YCCK/CMYK files with inverted data
346         if (mInfo.out_color_space == JCS_CMYK) {
347           type |= FLAVOR_SH(mInfo.saw_Adobe_marker ? 1 : 0);
348         }
349 #endif
350 
351         if (gfxPlatform::GetCMSOutputProfile()) {
352 
353           // Calculate rendering intent.
354           int intent = gfxPlatform::GetRenderingIntent();
355           if (intent == -1) {
356             intent = qcms_profile_get_rendering_intent(mInProfile);
357           }
358 
359           // Create the color management transform.
360           mTransform = qcms_transform_create(mInProfile,
361                                           type,
362                                           gfxPlatform::GetCMSOutputProfile(),
363                                           QCMS_DATA_RGB_8,
364                                           (qcms_intent)intent);
365         }
366       } else {
367 #ifdef DEBUG_tor
368         fprintf(stderr, "ICM profile colorspace mismatch\n");
369 #endif
370       }
371     }
372 
373     if (!mTransform) {
374       switch (mInfo.jpeg_color_space) {
375         case JCS_GRAYSCALE:
376         case JCS_RGB:
377         case JCS_YCbCr:
378 #ifdef JCS_EXTENSIONS
379           // if we're not color managing we can decode directly to
380           // MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB
381           if (mCMSMode != eCMSMode_All) {
382               mInfo.out_color_space = MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB;
383               mInfo.out_color_components = 4;
384           } else {
385               mInfo.out_color_space = JCS_RGB;
386           }
387 #else
388           mInfo.out_color_space = JCS_RGB;
389 #endif
390           break;
391         case JCS_CMYK:
392         case JCS_YCCK:
393           // libjpeg can convert from YCCK to CMYK, but not to RGB
394           mInfo.out_color_space = JCS_CMYK;
395           break;
396         default:
397           mState = JPEG_ERROR;
398           MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
399                  ("} (unknown colorpsace (3))"));
400           return Transition::TerminateFailure();
401       }
402     }
403 
404     // Don't allocate a giant and superfluous memory buffer
405     // when not doing a progressive decode.
406     mInfo.buffered_image = mDecodeStyle == PROGRESSIVE &&
407                            jpeg_has_multiple_scans(&mInfo);
408 
409     MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
410     nsresult rv = AllocateFrame(/* aFrameNum = */ 0, OutputSize(),
411                                 FullOutputFrame(), SurfaceFormat::B8G8R8X8);
412     if (NS_FAILED(rv)) {
413       mState = JPEG_ERROR;
414       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
415              ("} (could not initialize image frame)"));
416       return Transition::TerminateFailure();
417     }
418 
419     MOZ_ASSERT(mImageData, "Should have a buffer now");
420 
421     if (mDownscaler) {
422       nsresult rv = mDownscaler->BeginFrame(Size(), Nothing(),
423                                             mImageData,
424                                             /* aHasAlpha = */ false);
425       if (NS_FAILED(rv)) {
426         mState = JPEG_ERROR;
427         return Transition::TerminateFailure();
428       }
429     }
430 
431     MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
432            ("        JPEGDecoderAccounting: nsJPEGDecoder::"
433             "Write -- created image frame with %ux%u pixels",
434             mInfo.output_width, mInfo.output_height));
435 
436     mState = JPEG_START_DECOMPRESS;
437     MOZ_FALLTHROUGH; // to start decompressing.
438   }
439 
440   case JPEG_START_DECOMPRESS: {
441     LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::Write -- entering"
442                             " JPEG_START_DECOMPRESS case");
443     // Step 4: set parameters for decompression
444 
445     // FIXME -- Should reset dct_method and dither mode
446     // for final pass of progressive JPEG
447 
448     mInfo.dct_method =  JDCT_ISLOW;
449     mInfo.dither_mode = JDITHER_FS;
450     mInfo.do_fancy_upsampling = TRUE;
451     mInfo.enable_2pass_quant = FALSE;
452     mInfo.do_block_smoothing = TRUE;
453 
454     // Step 5: Start decompressor
455     if (jpeg_start_decompress(&mInfo) == FALSE) {
456       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
457              ("} (I/O suspension after jpeg_start_decompress())"));
458       return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
459     }
460 
461 #ifndef JCS_EXTENSIONS
462     /* Force to use our YCbCr to Packed RGB converter when possible */
463     if (!mTransform && (mCMSMode != eCMSMode_All) &&
464         mInfo.jpeg_color_space == JCS_YCbCr && mInfo.out_color_space == JCS_RGB) {
465       /* Special case for the most common case: transform from YCbCr direct into packed ARGB */
466       mInfo.out_color_components = 4; /* Packed ARGB pixels are always 4 bytes...*/
467       mInfo.cconvert->color_convert = ycc_rgb_convert_argb;
468     }
469 #endif
470 
471     // If this is a progressive JPEG ...
472     mState = mInfo.buffered_image ?
473              JPEG_DECOMPRESS_PROGRESSIVE : JPEG_DECOMPRESS_SEQUENTIAL;
474     MOZ_FALLTHROUGH; // to decompress sequential JPEG.
475   }
476 
477   case JPEG_DECOMPRESS_SEQUENTIAL: {
478     if (mState == JPEG_DECOMPRESS_SEQUENTIAL) {
479       LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::Write -- "
480                               "JPEG_DECOMPRESS_SEQUENTIAL case");
481 
482       bool suspend;
483       OutputScanlines(&suspend);
484 
485       if (suspend) {
486         MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
487                ("} (I/O suspension after OutputScanlines() - SEQUENTIAL)"));
488         return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
489       }
490 
491       // If we've completed image output ...
492       NS_ASSERTION(mInfo.output_scanline == mInfo.output_height,
493                    "We didn't process all of the data!");
494       mState = JPEG_DONE;
495     }
496     MOZ_FALLTHROUGH; // to decompress progressive JPEG.
497   }
498 
499   case JPEG_DECOMPRESS_PROGRESSIVE: {
500     if (mState == JPEG_DECOMPRESS_PROGRESSIVE) {
501       LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
502                 "nsJPEGDecoder::Write -- JPEG_DECOMPRESS_PROGRESSIVE case");
503 
504       int status;
505       do {
506         status = jpeg_consume_input(&mInfo);
507       } while ((status != JPEG_SUSPENDED) &&
508                (status != JPEG_REACHED_EOI));
509 
510       for (;;) {
511         if (mInfo.output_scanline == 0) {
512           int scan = mInfo.input_scan_number;
513 
514           // if we haven't displayed anything yet (output_scan_number==0)
515           // and we have enough data for a complete scan, force output
516           // of the last full scan
517           if ((mInfo.output_scan_number == 0) &&
518               (scan > 1) &&
519               (status != JPEG_REACHED_EOI))
520             scan--;
521 
522           if (!jpeg_start_output(&mInfo, scan)) {
523             MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
524                    ("} (I/O suspension after jpeg_start_output() -"
525                     " PROGRESSIVE)"));
526             return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
527           }
528         }
529 
530         if (mInfo.output_scanline == 0xffffff) {
531           mInfo.output_scanline = 0;
532         }
533 
534         bool suspend;
535         OutputScanlines(&suspend);
536 
537         if (suspend) {
538           if (mInfo.output_scanline == 0) {
539             // didn't manage to read any lines - flag so we don't call
540             // jpeg_start_output() multiple times for the same scan
541             mInfo.output_scanline = 0xffffff;
542           }
543           MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
544                  ("} (I/O suspension after OutputScanlines() - PROGRESSIVE)"));
545           return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
546         }
547 
548         if (mInfo.output_scanline == mInfo.output_height) {
549           if (!jpeg_finish_output(&mInfo)) {
550             MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
551                    ("} (I/O suspension after jpeg_finish_output() -"
552                     " PROGRESSIVE)"));
553             return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
554           }
555 
556           if (jpeg_input_complete(&mInfo) &&
557               (mInfo.input_scan_number == mInfo.output_scan_number))
558             break;
559 
560           mInfo.output_scanline = 0;
561           if (mDownscaler) {
562             mDownscaler->ResetForNextProgressivePass();
563           }
564         }
565       }
566 
567       mState = JPEG_DONE;
568     }
569     MOZ_FALLTHROUGH; // to finish decompressing.
570   }
571 
572   case JPEG_DONE: {
573     LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::ProcessData -- entering"
574                             " JPEG_DONE case");
575 
576     // Step 7: Finish decompression
577 
578     if (jpeg_finish_decompress(&mInfo) == FALSE) {
579       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
580              ("} (I/O suspension after jpeg_finish_decompress() - DONE)"));
581       return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
582     }
583 
584     // Make sure we don't feed any more data to libjpeg-turbo.
585     mState = JPEG_SINK_NON_JPEG_TRAILER;
586 
587     // We're done.
588     return Transition::TerminateSuccess();
589   }
590   case JPEG_SINK_NON_JPEG_TRAILER:
591     MOZ_LOG(sJPEGLog, LogLevel::Debug,
592            ("[this=%p] nsJPEGDecoder::ProcessData -- entering"
593             " JPEG_SINK_NON_JPEG_TRAILER case\n", this));
594 
595     MOZ_ASSERT_UNREACHABLE("Should stop getting data after entering state "
596                            "JPEG_SINK_NON_JPEG_TRAILER");
597 
598     return Transition::TerminateSuccess();
599 
600   case JPEG_ERROR:
601     MOZ_ASSERT_UNREACHABLE("Should stop getting data after entering state "
602                            "JPEG_ERROR");
603 
604     return Transition::TerminateFailure();
605   }
606 
607   MOZ_ASSERT_UNREACHABLE("Escaped the JPEG decoder state machine");
608   return Transition::TerminateFailure();
609 }
610 
611 LexerTransition<nsJPEGDecoder::State>
FinishedJPEGData()612 nsJPEGDecoder::FinishedJPEGData()
613 {
614   // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read
615   // all that data something is really wrong.
616   MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
617   return Transition::TerminateFailure();
618 }
619 
620 Orientation
ReadOrientationFromEXIF()621 nsJPEGDecoder::ReadOrientationFromEXIF()
622 {
623   jpeg_saved_marker_ptr marker;
624 
625   // Locate the APP1 marker, where EXIF data is stored, in the marker list.
626   for (marker = mInfo.marker_list ; marker != nullptr ; marker = marker->next) {
627     if (marker->marker == JPEG_APP0 + 1) {
628       break;
629     }
630   }
631 
632   // If we're at the end of the list, there's no EXIF data.
633   if (!marker) {
634     return Orientation();
635   }
636 
637   // Extract the orientation information.
638   EXIFData exif = EXIFParser::Parse(marker->data,
639                                     static_cast<uint32_t>(marker->data_length));
640   return exif.orientation;
641 }
642 
643 void
NotifyDone()644 nsJPEGDecoder::NotifyDone()
645 {
646   PostFrameStop(Opacity::FULLY_OPAQUE);
647   PostDecodeDone();
648 }
649 
650 void
OutputScanlines(bool * suspend)651 nsJPEGDecoder::OutputScanlines(bool* suspend)
652 {
653   *suspend = false;
654 
655   const uint32_t top = mInfo.output_scanline;
656 
657   while ((mInfo.output_scanline < mInfo.output_height)) {
658       uint32_t* imageRow = nullptr;
659       if (mDownscaler) {
660         imageRow = reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer());
661       } else {
662         imageRow = reinterpret_cast<uint32_t*>(mImageData) +
663                    (mInfo.output_scanline * mInfo.output_width);
664       }
665 
666       MOZ_ASSERT(imageRow, "Should have a row buffer here");
667 
668 #ifdef JCS_EXTENSIONS
669       if (mInfo.out_color_space == MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB) {
670 #else
671       if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) {
672 #endif
673         // Special case: scanline will be directly converted into packed ARGB
674         if (jpeg_read_scanlines(&mInfo, (JSAMPARRAY)&imageRow, 1) != 1) {
675           *suspend = true; // suspend
676           break;
677         }
678         if (mDownscaler) {
679           mDownscaler->CommitRow();
680         }
681         continue; // all done for this row!
682       }
683 
684       JSAMPROW sampleRow = (JSAMPROW)imageRow;
685       if (mInfo.output_components == 3) {
686         // Put the pixels at end of row to enable in-place expansion
687         sampleRow += mInfo.output_width;
688       }
689 
690       // Request one scanline.  Returns 0 or 1 scanlines.
691       if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) {
692         *suspend = true; // suspend
693         break;
694       }
695 
696       if (mTransform) {
697         JSAMPROW source = sampleRow;
698         if (mInfo.out_color_space == JCS_GRAYSCALE) {
699           // Convert from the 1byte grey pixels at begin of row
700           // to the 3byte RGB byte pixels at 'end' of row
701           sampleRow += mInfo.output_width;
702         }
703         qcms_transform_data(mTransform, source, sampleRow, mInfo.output_width);
704         // Move 3byte RGB data to end of row
705         if (mInfo.out_color_space == JCS_CMYK) {
706           memmove(sampleRow + mInfo.output_width,
707                   sampleRow,
708                   3 * mInfo.output_width);
709           sampleRow += mInfo.output_width;
710         }
711       } else {
712         if (mInfo.out_color_space == JCS_CMYK) {
713           // Convert from CMYK to RGB
714           // We cannot convert directly to Cairo, as the CMSRGBTransform
715           // may wants to do a RGB transform...
716           // Would be better to have platform CMSenabled transformation
717           // from CMYK to (A)RGB...
718           cmyk_convert_rgb((JSAMPROW)imageRow, mInfo.output_width);
719           sampleRow += mInfo.output_width;
720         }
721         if (mCMSMode == eCMSMode_All) {
722           // No embedded ICC profile - treat as sRGB
723           qcms_transform* transform = gfxPlatform::GetCMSRGBTransform();
724           if (transform) {
725             qcms_transform_data(transform, sampleRow, sampleRow,
726                                 mInfo.output_width);
727           }
728         }
729       }
730 
731       // counter for while() loops below
732       uint32_t idx = mInfo.output_width;
733 
734       // copy as bytes until source pointer is 32-bit-aligned
735       for (; (NS_PTR_TO_UINT32(sampleRow) & 0x3) && idx; --idx) {
736         *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1],
737                                      sampleRow[2]);
738         sampleRow += 3;
739       }
740 
741       // copy pixels in blocks of 4
742       while (idx >= 4) {
743         GFX_BLOCK_RGB_TO_FRGB(sampleRow, imageRow);
744         idx       -=  4;
745         sampleRow += 12;
746         imageRow  +=  4;
747       }
748 
749       // copy remaining pixel(s)
750       while (idx--) {
751         // 32-bit read of final pixel will exceed buffer, so read bytes
752         *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1],
753                                      sampleRow[2]);
754         sampleRow += 3;
755       }
756 
757       if (mDownscaler) {
758         mDownscaler->CommitRow();
759       }
760   }
761 
762   if (mDownscaler && mDownscaler->HasInvalidation()) {
763     DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
764     PostInvalidation(invalidRect.mOriginalSizeRect,
765                      Some(invalidRect.mTargetSizeRect));
766     MOZ_ASSERT(!mDownscaler->HasInvalidation());
767   } else if (!mDownscaler && top != mInfo.output_scanline) {
768     PostInvalidation(nsIntRect(0, top,
769                                mInfo.output_width,
770                                mInfo.output_scanline - top));
771   }
772 }
773 
774 // Override the standard error method in the IJG JPEG decoder code.
775 METHODDEF(void)
776 my_error_exit (j_common_ptr cinfo)
777 {
778   decoder_error_mgr* err = (decoder_error_mgr*) cinfo->err;
779 
780   // Convert error to a browser error code
781   nsresult error_code = err->pub.msg_code == JERR_OUT_OF_MEMORY
782                       ? NS_ERROR_OUT_OF_MEMORY
783                       : NS_ERROR_FAILURE;
784 
785 #ifdef DEBUG
786   char buffer[JMSG_LENGTH_MAX];
787 
788   // Create the message
789   (*err->pub.format_message) (cinfo, buffer);
790 
791   fprintf(stderr, "JPEG decoding error:\n%s\n", buffer);
792 #endif
793 
794   // Return control to the setjmp point.  We pass an nsresult masquerading as
795   // an int, which works because the setjmp() caller casts it back.
796   longjmp(err->setjmp_buffer, static_cast<int>(error_code));
797 }
798 
799 /*******************************************************************************
800  * This is the callback routine from the IJG JPEG library used to supply new
801  * data to the decompressor when its input buffer is exhausted.  It juggles
802  * multiple buffers in an attempt to avoid unnecessary copying of input data.
803  *
804  * (A simpler scheme is possible: It's much easier to use only a single
805  * buffer; when fill_input_buffer() is called, move any unconsumed data
806  * (beyond the current pointer/count) down to the beginning of this buffer and
807  * then load new data into the remaining buffer space.  This approach requires
808  * a little more data copying but is far easier to get right.)
809  *
810  * At any one time, the JPEG decompressor is either reading from the necko
811  * input buffer, which is volatile across top-level calls to the IJG library,
812  * or the "backtrack" buffer.  The backtrack buffer contains the remaining
813  * unconsumed data from the necko buffer after parsing was suspended due
814  * to insufficient data in some previous call to the IJG library.
815  *
816  * When suspending, the decompressor will back up to a convenient restart
817  * point (typically the start of the current MCU). The variables
818  * next_input_byte & bytes_in_buffer indicate where the restart point will be
819  * if the current call returns FALSE.  Data beyond this point must be
820  * rescanned after resumption, so it must be preserved in case the decompressor
821  * decides to backtrack.
822  *
823  * Returns:
824  *  TRUE if additional data is available, FALSE if no data present and
825  *   the JPEG library should therefore suspend processing of input stream
826  ******************************************************************************/
827 
828 /******************************************************************************/
829 /* data source manager method                                                 */
830 /******************************************************************************/
831 
832 /******************************************************************************/
833 /* data source manager method
834         Initialize source.  This is called by jpeg_read_header() before any
835         data is actually read.  May leave
836         bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
837         will occur immediately).
838 */
839 METHODDEF(void)
840 init_source (j_decompress_ptr jd)
841 {
842 }
843 
844 /******************************************************************************/
845 /* data source manager method
846         Skip num_bytes worth of data.  The buffer pointer and count should
847         be advanced over num_bytes input bytes, refilling the buffer as
848         needed.  This is used to skip over a potentially large amount of
849         uninteresting data (such as an APPn marker).  In some applications
850         it may be possible to optimize away the reading of the skipped data,
851         but it's not clear that being smart is worth much trouble; large
852         skips are uncommon.  bytes_in_buffer may be zero on return.
853         A zero or negative skip count should be treated as a no-op.
854 */
855 METHODDEF(void)
856 skip_input_data (j_decompress_ptr jd, long num_bytes)
857 {
858   struct jpeg_source_mgr* src = jd->src;
859   nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
860 
861   if (num_bytes > (long)src->bytes_in_buffer) {
862     // Can't skip it all right now until we get more data from
863     // network stream. Set things up so that fill_input_buffer
864     // will skip remaining amount.
865     decoder->mBytesToSkip = (size_t)num_bytes - src->bytes_in_buffer;
866     src->next_input_byte += src->bytes_in_buffer;
867     src->bytes_in_buffer = 0;
868 
869   } else {
870     // Simple case. Just advance buffer pointer
871 
872     src->bytes_in_buffer -= (size_t)num_bytes;
873     src->next_input_byte += num_bytes;
874   }
875 }
876 
877 /******************************************************************************/
878 /* data source manager method
879         This is called whenever bytes_in_buffer has reached zero and more
880         data is wanted.  In typical applications, it should read fresh data
881         into the buffer (ignoring the current state of next_input_byte and
882         bytes_in_buffer), reset the pointer & count to the start of the
883         buffer, and return TRUE indicating that the buffer has been reloaded.
884         It is not necessary to fill the buffer entirely, only to obtain at
885         least one more byte.  bytes_in_buffer MUST be set to a positive value
886         if TRUE is returned.  A FALSE return should only be used when I/O
887         suspension is desired.
888 */
889 METHODDEF(boolean)
890 fill_input_buffer (j_decompress_ptr jd)
891 {
892   struct jpeg_source_mgr* src = jd->src;
893   nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
894 
895   if (decoder->mReading) {
896     const JOCTET* new_buffer = decoder->mSegment;
897     uint32_t new_buflen = decoder->mSegmentLen;
898 
899     if (!new_buffer || new_buflen == 0) {
900       return false; // suspend
901     }
902 
903     decoder->mSegmentLen = 0;
904 
905     if (decoder->mBytesToSkip) {
906       if (decoder->mBytesToSkip < new_buflen) {
907         // All done skipping bytes; Return what's left.
908         new_buffer += decoder->mBytesToSkip;
909         new_buflen -= decoder->mBytesToSkip;
910         decoder->mBytesToSkip = 0;
911       } else {
912         // Still need to skip some more data in the future
913         decoder->mBytesToSkip -= (size_t)new_buflen;
914         return false; // suspend
915       }
916     }
917 
918     decoder->mBackBufferUnreadLen = src->bytes_in_buffer;
919 
920     src->next_input_byte = new_buffer;
921     src->bytes_in_buffer = (size_t)new_buflen;
922     decoder->mReading = false;
923 
924     return true;
925   }
926 
927   if (src->next_input_byte != decoder->mSegment) {
928     // Backtrack data has been permanently consumed.
929     decoder->mBackBufferUnreadLen = 0;
930     decoder->mBackBufferLen = 0;
931   }
932 
933   // Save remainder of netlib buffer in backtrack buffer
934   const uint32_t new_backtrack_buflen = src->bytes_in_buffer +
935                                         decoder->mBackBufferLen;
936 
937   // Make sure backtrack buffer is big enough to hold new data.
938   if (decoder->mBackBufferSize < new_backtrack_buflen) {
939     // Check for malformed MARKER segment lengths, before allocating space
940     // for it
941     if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
942       my_error_exit((j_common_ptr)(&decoder->mInfo));
943     }
944 
945     // Round up to multiple of 256 bytes.
946     const size_t roundup_buflen = ((new_backtrack_buflen + 255) >> 8) << 8;
947     JOCTET* buf = (JOCTET*)PR_REALLOC(decoder->mBackBuffer, roundup_buflen);
948     // Check for OOM
949     if (!buf) {
950       decoder->mInfo.err->msg_code = JERR_OUT_OF_MEMORY;
951       my_error_exit((j_common_ptr)(&decoder->mInfo));
952     }
953     decoder->mBackBuffer = buf;
954     decoder->mBackBufferSize = roundup_buflen;
955   }
956 
957   // Copy remainder of netlib segment into backtrack buffer.
958   memmove(decoder->mBackBuffer + decoder->mBackBufferLen,
959           src->next_input_byte,
960           src->bytes_in_buffer);
961 
962   // Point to start of data to be rescanned.
963   src->next_input_byte = decoder->mBackBuffer + decoder->mBackBufferLen -
964                          decoder->mBackBufferUnreadLen;
965   src->bytes_in_buffer += decoder->mBackBufferUnreadLen;
966   decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
967   decoder->mReading = true;
968 
969   return false;
970 }
971 
972 /******************************************************************************/
973 /* data source manager method */
974 /*
975  * Terminate source --- called by jpeg_finish_decompress() after all
976  * data has been read to clean up JPEG source manager. NOT called by
977  * jpeg_abort() or jpeg_destroy().
978  */
979 METHODDEF(void)
980 term_source (j_decompress_ptr jd)
981 {
982   nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
983 
984   // This function shouldn't be called if we ran into an error we didn't
985   // recover from.
986   MOZ_ASSERT(decoder->mState != JPEG_ERROR,
987              "Calling term_source on a JPEG with mState == JPEG_ERROR!");
988 
989   // Notify using a helper method to get around protectedness issues.
990   decoder->NotifyDone();
991 }
992 
993 } // namespace image
994 } // namespace mozilla
995 
996 #ifndef JCS_EXTENSIONS
997 /**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/
998 
999 /*
1000  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
1001  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
1002  * The conversion equations to be implemented are therefore
1003  *      R = Y                + 1.40200 * Cr
1004  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
1005  *      B = Y + 1.77200 * Cb
1006  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
1007  * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
1008  *
1009  * To avoid floating-point arithmetic, we represent the fractional constants
1010  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
1011  * the products by 2^16, with appropriate rounding, to get the correct answer.
1012  * Notice that Y, being an integral input, does not contribute any fraction
1013  * so it need not participate in the rounding.
1014  *
1015  * For even more speed, we avoid doing any multiplications in the inner loop
1016  * by precalculating the constants times Cb and Cr for all possible values.
1017  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
1018  * for 12-bit samples it is still acceptable.  It's not very reasonable for
1019  * 16-bit samples, but if you want lossless storage you shouldn't be changing
1020  * colorspace anyway.
1021  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
1022  * values for the G calculation are left scaled up, since we must add them
1023  * together before rounding.
1024  */
1025 
1026 #define SCALEBITS       16      /* speediest right-shift on some machines */
1027 
1028 /* Use static tables for color processing. */
1029 /* Four tables, each 256 entries of 4 bytes totals 4K which is not bad... */
1030 
1031 const int Cr_r_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1032        -0xb3,       -0xb2,       -0xb1,       -0xaf,       -0xae,       -0xac,
1033        -0xab,       -0xaa,       -0xa8,       -0xa7,       -0xa5,       -0xa4,
1034        -0xa3,       -0xa1,       -0xa0,       -0x9e,       -0x9d,       -0x9c,
1035        -0x9a,       -0x99,       -0x97,       -0x96,       -0x95,       -0x93,
1036        -0x92,       -0x90,       -0x8f,       -0x8e,       -0x8c,       -0x8b,
1037        -0x89,       -0x88,       -0x87,       -0x85,       -0x84,       -0x82,
1038        -0x81,       -0x80,       -0x7e,       -0x7d,       -0x7b,       -0x7a,
1039        -0x79,       -0x77,       -0x76,       -0x74,       -0x73,       -0x72,
1040        -0x70,       -0x6f,       -0x6d,       -0x6c,       -0x6b,       -0x69,
1041        -0x68,       -0x66,       -0x65,       -0x64,       -0x62,       -0x61,
1042        -0x5f,       -0x5e,       -0x5d,       -0x5b,       -0x5a,       -0x58,
1043        -0x57,       -0x56,       -0x54,       -0x53,       -0x51,       -0x50,
1044        -0x4f,       -0x4d,       -0x4c,       -0x4a,       -0x49,       -0x48,
1045        -0x46,       -0x45,       -0x43,       -0x42,       -0x40,       -0x3f,
1046        -0x3e,       -0x3c,       -0x3b,       -0x39,       -0x38,       -0x37,
1047        -0x35,       -0x34,       -0x32,       -0x31,       -0x30,       -0x2e,
1048        -0x2d,       -0x2b,       -0x2a,       -0x29,       -0x27,       -0x26,
1049        -0x24,       -0x23,       -0x22,       -0x20,       -0x1f,       -0x1d,
1050        -0x1c,       -0x1b,       -0x19,       -0x18,       -0x16,       -0x15,
1051        -0x14,       -0x12,       -0x11,       -0x0f,       -0x0e,       -0x0d,
1052        -0x0b,       -0x0a,       -0x08,       -0x07,       -0x06,       -0x04,
1053        -0x03,       -0x01,        0x00,        0x01,        0x03,        0x04,
1054         0x06,        0x07,        0x08,        0x0a,        0x0b,        0x0d,
1055         0x0e,        0x0f,        0x11,        0x12,        0x14,        0x15,
1056         0x16,        0x18,        0x19,        0x1b,        0x1c,        0x1d,
1057         0x1f,        0x20,        0x22,        0x23,        0x24,        0x26,
1058         0x27,        0x29,        0x2a,        0x2b,        0x2d,        0x2e,
1059         0x30,        0x31,        0x32,        0x34,        0x35,        0x37,
1060         0x38,        0x39,        0x3b,        0x3c,        0x3e,        0x3f,
1061         0x40,        0x42,        0x43,        0x45,        0x46,        0x48,
1062         0x49,        0x4a,        0x4c,        0x4d,        0x4f,        0x50,
1063         0x51,        0x53,        0x54,        0x56,        0x57,        0x58,
1064         0x5a,        0x5b,        0x5d,        0x5e,        0x5f,        0x61,
1065         0x62,        0x64,        0x65,        0x66,        0x68,        0x69,
1066         0x6b,        0x6c,        0x6d,        0x6f,        0x70,        0x72,
1067         0x73,        0x74,        0x76,        0x77,        0x79,        0x7a,
1068         0x7b,        0x7d,        0x7e,        0x80,        0x81,        0x82,
1069         0x84,        0x85,        0x87,        0x88,        0x89,        0x8b,
1070         0x8c,        0x8e,        0x8f,        0x90,        0x92,        0x93,
1071         0x95,        0x96,        0x97,        0x99,        0x9a,        0x9c,
1072         0x9d,        0x9e,        0xa0,        0xa1,        0xa3,        0xa4,
1073         0xa5,        0xa7,        0xa8,        0xaa,        0xab,        0xac,
1074         0xae,        0xaf,        0xb1,        0xb2,
1075   };
1076 
1077 const int Cb_b_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1078        -0xe3,       -0xe1,       -0xdf,       -0xde,       -0xdc,       -0xda,
1079        -0xd8,       -0xd6,       -0xd5,       -0xd3,       -0xd1,       -0xcf,
1080        -0xce,       -0xcc,       -0xca,       -0xc8,       -0xc6,       -0xc5,
1081        -0xc3,       -0xc1,       -0xbf,       -0xbe,       -0xbc,       -0xba,
1082        -0xb8,       -0xb7,       -0xb5,       -0xb3,       -0xb1,       -0xaf,
1083        -0xae,       -0xac,       -0xaa,       -0xa8,       -0xa7,       -0xa5,
1084        -0xa3,       -0xa1,       -0x9f,       -0x9e,       -0x9c,       -0x9a,
1085        -0x98,       -0x97,       -0x95,       -0x93,       -0x91,       -0x90,
1086        -0x8e,       -0x8c,       -0x8a,       -0x88,       -0x87,       -0x85,
1087        -0x83,       -0x81,       -0x80,       -0x7e,       -0x7c,       -0x7a,
1088        -0x78,       -0x77,       -0x75,       -0x73,       -0x71,       -0x70,
1089        -0x6e,       -0x6c,       -0x6a,       -0x69,       -0x67,       -0x65,
1090        -0x63,       -0x61,       -0x60,       -0x5e,       -0x5c,       -0x5a,
1091        -0x59,       -0x57,       -0x55,       -0x53,       -0x52,       -0x50,
1092        -0x4e,       -0x4c,       -0x4a,       -0x49,       -0x47,       -0x45,
1093        -0x43,       -0x42,       -0x40,       -0x3e,       -0x3c,       -0x3a,
1094        -0x39,       -0x37,       -0x35,       -0x33,       -0x32,       -0x30,
1095        -0x2e,       -0x2c,       -0x2b,       -0x29,       -0x27,       -0x25,
1096        -0x23,       -0x22,       -0x20,       -0x1e,       -0x1c,       -0x1b,
1097        -0x19,       -0x17,       -0x15,       -0x13,       -0x12,       -0x10,
1098        -0x0e,       -0x0c,       -0x0b,       -0x09,       -0x07,       -0x05,
1099        -0x04,       -0x02,        0x00,        0x02,        0x04,        0x05,
1100         0x07,        0x09,        0x0b,        0x0c,        0x0e,        0x10,
1101         0x12,        0x13,        0x15,        0x17,        0x19,        0x1b,
1102         0x1c,        0x1e,        0x20,        0x22,        0x23,        0x25,
1103         0x27,        0x29,        0x2b,        0x2c,        0x2e,        0x30,
1104         0x32,        0x33,        0x35,        0x37,        0x39,        0x3a,
1105         0x3c,        0x3e,        0x40,        0x42,        0x43,        0x45,
1106         0x47,        0x49,        0x4a,        0x4c,        0x4e,        0x50,
1107         0x52,        0x53,        0x55,        0x57,        0x59,        0x5a,
1108         0x5c,        0x5e,        0x60,        0x61,        0x63,        0x65,
1109         0x67,        0x69,        0x6a,        0x6c,        0x6e,        0x70,
1110         0x71,        0x73,        0x75,        0x77,        0x78,        0x7a,
1111         0x7c,        0x7e,        0x80,        0x81,        0x83,        0x85,
1112         0x87,        0x88,        0x8a,        0x8c,        0x8e,        0x90,
1113         0x91,        0x93,        0x95,        0x97,        0x98,        0x9a,
1114         0x9c,        0x9e,        0x9f,        0xa1,        0xa3,        0xa5,
1115         0xa7,        0xa8,        0xaa,        0xac,        0xae,        0xaf,
1116         0xb1,        0xb3,        0xb5,        0xb7,        0xb8,        0xba,
1117         0xbc,        0xbe,        0xbf,        0xc1,        0xc3,        0xc5,
1118         0xc6,        0xc8,        0xca,        0xcc,        0xce,        0xcf,
1119         0xd1,        0xd3,        0xd5,        0xd6,        0xd8,        0xda,
1120         0xdc,        0xde,        0xdf,        0xe1,
1121   };
1122 
1123 const int Cr_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1124     0x5b6900,    0x5ab22e,    0x59fb5c,    0x59448a,    0x588db8,    0x57d6e6,
1125     0x572014,    0x566942,    0x55b270,    0x54fb9e,    0x5444cc,    0x538dfa,
1126     0x52d728,    0x522056,    0x516984,    0x50b2b2,    0x4ffbe0,    0x4f450e,
1127     0x4e8e3c,    0x4dd76a,    0x4d2098,    0x4c69c6,    0x4bb2f4,    0x4afc22,
1128     0x4a4550,    0x498e7e,    0x48d7ac,    0x4820da,    0x476a08,    0x46b336,
1129     0x45fc64,    0x454592,    0x448ec0,    0x43d7ee,    0x43211c,    0x426a4a,
1130     0x41b378,    0x40fca6,    0x4045d4,    0x3f8f02,    0x3ed830,    0x3e215e,
1131     0x3d6a8c,    0x3cb3ba,    0x3bfce8,    0x3b4616,    0x3a8f44,    0x39d872,
1132     0x3921a0,    0x386ace,    0x37b3fc,    0x36fd2a,    0x364658,    0x358f86,
1133     0x34d8b4,    0x3421e2,    0x336b10,    0x32b43e,    0x31fd6c,    0x31469a,
1134     0x308fc8,    0x2fd8f6,    0x2f2224,    0x2e6b52,    0x2db480,    0x2cfdae,
1135     0x2c46dc,    0x2b900a,    0x2ad938,    0x2a2266,    0x296b94,    0x28b4c2,
1136     0x27fdf0,    0x27471e,    0x26904c,    0x25d97a,    0x2522a8,    0x246bd6,
1137     0x23b504,    0x22fe32,    0x224760,    0x21908e,    0x20d9bc,    0x2022ea,
1138     0x1f6c18,    0x1eb546,    0x1dfe74,    0x1d47a2,    0x1c90d0,    0x1bd9fe,
1139     0x1b232c,    0x1a6c5a,    0x19b588,    0x18feb6,    0x1847e4,    0x179112,
1140     0x16da40,    0x16236e,    0x156c9c,    0x14b5ca,    0x13fef8,    0x134826,
1141     0x129154,    0x11da82,    0x1123b0,    0x106cde,    0x0fb60c,    0x0eff3a,
1142     0x0e4868,    0x0d9196,    0x0cdac4,    0x0c23f2,    0x0b6d20,    0x0ab64e,
1143     0x09ff7c,    0x0948aa,    0x0891d8,    0x07db06,    0x072434,    0x066d62,
1144     0x05b690,    0x04ffbe,    0x0448ec,    0x03921a,    0x02db48,    0x022476,
1145     0x016da4,    0x00b6d2,    0x000000,   -0x00b6d2,   -0x016da4,   -0x022476,
1146    -0x02db48,   -0x03921a,   -0x0448ec,   -0x04ffbe,   -0x05b690,   -0x066d62,
1147    -0x072434,   -0x07db06,   -0x0891d8,   -0x0948aa,   -0x09ff7c,   -0x0ab64e,
1148    -0x0b6d20,   -0x0c23f2,   -0x0cdac4,   -0x0d9196,   -0x0e4868,   -0x0eff3a,
1149    -0x0fb60c,   -0x106cde,   -0x1123b0,   -0x11da82,   -0x129154,   -0x134826,
1150    -0x13fef8,   -0x14b5ca,   -0x156c9c,   -0x16236e,   -0x16da40,   -0x179112,
1151    -0x1847e4,   -0x18feb6,   -0x19b588,   -0x1a6c5a,   -0x1b232c,   -0x1bd9fe,
1152    -0x1c90d0,   -0x1d47a2,   -0x1dfe74,   -0x1eb546,   -0x1f6c18,   -0x2022ea,
1153    -0x20d9bc,   -0x21908e,   -0x224760,   -0x22fe32,   -0x23b504,   -0x246bd6,
1154    -0x2522a8,   -0x25d97a,   -0x26904c,   -0x27471e,   -0x27fdf0,   -0x28b4c2,
1155    -0x296b94,   -0x2a2266,   -0x2ad938,   -0x2b900a,   -0x2c46dc,   -0x2cfdae,
1156    -0x2db480,   -0x2e6b52,   -0x2f2224,   -0x2fd8f6,   -0x308fc8,   -0x31469a,
1157    -0x31fd6c,   -0x32b43e,   -0x336b10,   -0x3421e2,   -0x34d8b4,   -0x358f86,
1158    -0x364658,   -0x36fd2a,   -0x37b3fc,   -0x386ace,   -0x3921a0,   -0x39d872,
1159    -0x3a8f44,   -0x3b4616,   -0x3bfce8,   -0x3cb3ba,   -0x3d6a8c,   -0x3e215e,
1160    -0x3ed830,   -0x3f8f02,   -0x4045d4,   -0x40fca6,   -0x41b378,   -0x426a4a,
1161    -0x43211c,   -0x43d7ee,   -0x448ec0,   -0x454592,   -0x45fc64,   -0x46b336,
1162    -0x476a08,   -0x4820da,   -0x48d7ac,   -0x498e7e,   -0x4a4550,   -0x4afc22,
1163    -0x4bb2f4,   -0x4c69c6,   -0x4d2098,   -0x4dd76a,   -0x4e8e3c,   -0x4f450e,
1164    -0x4ffbe0,   -0x50b2b2,   -0x516984,   -0x522056,   -0x52d728,   -0x538dfa,
1165    -0x5444cc,   -0x54fb9e,   -0x55b270,   -0x566942,   -0x572014,   -0x57d6e6,
1166    -0x588db8,   -0x59448a,   -0x59fb5c,   -0x5ab22e,
1167  };
1168 
1169 const int Cb_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1170     0x2c8d00,    0x2c34e6,    0x2bdccc,    0x2b84b2,    0x2b2c98,    0x2ad47e,
1171     0x2a7c64,    0x2a244a,    0x29cc30,    0x297416,    0x291bfc,    0x28c3e2,
1172     0x286bc8,    0x2813ae,    0x27bb94,    0x27637a,    0x270b60,    0x26b346,
1173     0x265b2c,    0x260312,    0x25aaf8,    0x2552de,    0x24fac4,    0x24a2aa,
1174     0x244a90,    0x23f276,    0x239a5c,    0x234242,    0x22ea28,    0x22920e,
1175     0x2239f4,    0x21e1da,    0x2189c0,    0x2131a6,    0x20d98c,    0x208172,
1176     0x202958,    0x1fd13e,    0x1f7924,    0x1f210a,    0x1ec8f0,    0x1e70d6,
1177     0x1e18bc,    0x1dc0a2,    0x1d6888,    0x1d106e,    0x1cb854,    0x1c603a,
1178     0x1c0820,    0x1bb006,    0x1b57ec,    0x1affd2,    0x1aa7b8,    0x1a4f9e,
1179     0x19f784,    0x199f6a,    0x194750,    0x18ef36,    0x18971c,    0x183f02,
1180     0x17e6e8,    0x178ece,    0x1736b4,    0x16de9a,    0x168680,    0x162e66,
1181     0x15d64c,    0x157e32,    0x152618,    0x14cdfe,    0x1475e4,    0x141dca,
1182     0x13c5b0,    0x136d96,    0x13157c,    0x12bd62,    0x126548,    0x120d2e,
1183     0x11b514,    0x115cfa,    0x1104e0,    0x10acc6,    0x1054ac,    0x0ffc92,
1184     0x0fa478,    0x0f4c5e,    0x0ef444,    0x0e9c2a,    0x0e4410,    0x0debf6,
1185     0x0d93dc,    0x0d3bc2,    0x0ce3a8,    0x0c8b8e,    0x0c3374,    0x0bdb5a,
1186     0x0b8340,    0x0b2b26,    0x0ad30c,    0x0a7af2,    0x0a22d8,    0x09cabe,
1187     0x0972a4,    0x091a8a,    0x08c270,    0x086a56,    0x08123c,    0x07ba22,
1188     0x076208,    0x0709ee,    0x06b1d4,    0x0659ba,    0x0601a0,    0x05a986,
1189     0x05516c,    0x04f952,    0x04a138,    0x04491e,    0x03f104,    0x0398ea,
1190     0x0340d0,    0x02e8b6,    0x02909c,    0x023882,    0x01e068,    0x01884e,
1191     0x013034,    0x00d81a,    0x008000,    0x0027e6,   -0x003034,   -0x00884e,
1192    -0x00e068,   -0x013882,   -0x01909c,   -0x01e8b6,   -0x0240d0,   -0x0298ea,
1193    -0x02f104,   -0x03491e,   -0x03a138,   -0x03f952,   -0x04516c,   -0x04a986,
1194    -0x0501a0,   -0x0559ba,   -0x05b1d4,   -0x0609ee,   -0x066208,   -0x06ba22,
1195    -0x07123c,   -0x076a56,   -0x07c270,   -0x081a8a,   -0x0872a4,   -0x08cabe,
1196    -0x0922d8,   -0x097af2,   -0x09d30c,   -0x0a2b26,   -0x0a8340,   -0x0adb5a,
1197    -0x0b3374,   -0x0b8b8e,   -0x0be3a8,   -0x0c3bc2,   -0x0c93dc,   -0x0cebf6,
1198    -0x0d4410,   -0x0d9c2a,   -0x0df444,   -0x0e4c5e,   -0x0ea478,   -0x0efc92,
1199    -0x0f54ac,   -0x0facc6,   -0x1004e0,   -0x105cfa,   -0x10b514,   -0x110d2e,
1200    -0x116548,   -0x11bd62,   -0x12157c,   -0x126d96,   -0x12c5b0,   -0x131dca,
1201    -0x1375e4,   -0x13cdfe,   -0x142618,   -0x147e32,   -0x14d64c,   -0x152e66,
1202    -0x158680,   -0x15de9a,   -0x1636b4,   -0x168ece,   -0x16e6e8,   -0x173f02,
1203    -0x17971c,   -0x17ef36,   -0x184750,   -0x189f6a,   -0x18f784,   -0x194f9e,
1204    -0x19a7b8,   -0x19ffd2,   -0x1a57ec,   -0x1ab006,   -0x1b0820,   -0x1b603a,
1205    -0x1bb854,   -0x1c106e,   -0x1c6888,   -0x1cc0a2,   -0x1d18bc,   -0x1d70d6,
1206    -0x1dc8f0,   -0x1e210a,   -0x1e7924,   -0x1ed13e,   -0x1f2958,   -0x1f8172,
1207    -0x1fd98c,   -0x2031a6,   -0x2089c0,   -0x20e1da,   -0x2139f4,   -0x21920e,
1208    -0x21ea28,   -0x224242,   -0x229a5c,   -0x22f276,   -0x234a90,   -0x23a2aa,
1209    -0x23fac4,   -0x2452de,   -0x24aaf8,   -0x250312,   -0x255b2c,   -0x25b346,
1210    -0x260b60,   -0x26637a,   -0x26bb94,   -0x2713ae,   -0x276bc8,   -0x27c3e2,
1211    -0x281bfc,   -0x287416,   -0x28cc30,   -0x29244a,   -0x297c64,   -0x29d47e,
1212    -0x2a2c98,   -0x2a84b2,   -0x2adccc,   -0x2b34e6,
1213  };
1214 
1215 
1216 /* We assume that right shift corresponds to signed division by 2 with
1217  * rounding towards minus infinity.  This is correct for typical "arithmetic
1218  * shift" instructions that shift in copies of the sign bit.  But some
1219  * C compilers implement >> with an unsigned shift.  For these machines you
1220  * must define RIGHT_SHIFT_IS_UNSIGNED.
1221  * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
1222  * It is only applied with constant shift counts.  SHIFT_TEMPS must be
1223  * included in the variables of any routine using RIGHT_SHIFT.
1224  */
1225 
1226 #ifdef RIGHT_SHIFT_IS_UNSIGNED
1227 #define SHIFT_TEMPS	INT32 shift_temp;
1228 #define RIGHT_SHIFT(x,shft)  \
1229 	((shift_temp = (x)) < 0 ? \
1230 	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
1231 	 (shift_temp >> (shft)))
1232 #else
1233 #define SHIFT_TEMPS
1234 #define RIGHT_SHIFT(x,shft)	((x) >> (shft))
1235 #endif
1236 
1237 
1238 METHODDEF(void)
ycc_rgb_convert_argb(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)1239 ycc_rgb_convert_argb (j_decompress_ptr cinfo,
1240                  JSAMPIMAGE input_buf, JDIMENSION input_row,
1241                  JSAMPARRAY output_buf, int num_rows)
1242 {
1243   JDIMENSION num_cols = cinfo->output_width;
1244   JSAMPLE * range_limit = cinfo->sample_range_limit;
1245 
1246   SHIFT_TEMPS
1247 
1248   /* This is used if we don't have SSE2 */
1249 
1250   while (--num_rows >= 0) {
1251     JSAMPROW inptr0 = input_buf[0][input_row];
1252     JSAMPROW inptr1 = input_buf[1][input_row];
1253     JSAMPROW inptr2 = input_buf[2][input_row];
1254     input_row++;
1255     uint32_t *outptr = (uint32_t *) *output_buf++;
1256     for (JDIMENSION col = 0; col < num_cols; col++) {
1257       int y  = GETJSAMPLE(inptr0[col]);
1258       int cb = GETJSAMPLE(inptr1[col]);
1259       int cr = GETJSAMPLE(inptr2[col]);
1260       JSAMPLE * range_limit_y = range_limit + y;
1261       /* Range-limiting is essential due to noise introduced by DCT losses. */
1262       outptr[col] = 0xFF000000 |
1263                     ( range_limit_y[Cr_r_tab[cr]] << 16 ) |
1264                     ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) |
1265                     ( range_limit_y[Cb_b_tab[cb]] );
1266     }
1267   }
1268 }
1269 #endif
1270 
1271 
1272 ///*************** Inverted CMYK -> RGB conversion *************************
1273 /// Input is (Inverted) CMYK stored as 4 bytes per pixel.
1274 /// Output is RGB stored as 3 bytes per pixel.
1275 /// @param row Points to row buffer containing the CMYK bytes for each pixel
1276 /// in the row.
1277 /// @param width Number of pixels in the row.
cmyk_convert_rgb(JSAMPROW row,JDIMENSION width)1278 static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width)
1279 {
1280   // Work from end to front to shrink from 4 bytes per pixel to 3
1281   JSAMPROW in = row + width*4;
1282   JSAMPROW out = in;
1283 
1284   for (uint32_t i = width; i > 0; i--) {
1285     in -= 4;
1286     out -= 3;
1287 
1288     // Source is 'Inverted CMYK', output is RGB.
1289     // See: http://www.easyrgb.com/math.php?MATH=M12#text12
1290     // Or:  http://www.ilkeratalay.com/colorspacesfaq.php#rgb
1291 
1292     // From CMYK to CMY
1293     // C = ( C * ( 1 - K ) + K )
1294     // M = ( M * ( 1 - K ) + K )
1295     // Y = ( Y * ( 1 - K ) + K )
1296 
1297     // From Inverted CMYK to CMY is thus:
1298     // C = ( (1-iC) * (1 - (1-iK)) + (1-iK) ) => 1 - iC*iK
1299     // Same for M and Y
1300 
1301     // Convert from CMY (0..1) to RGB (0..1)
1302     // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
1303     // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
1304     // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
1305 
1306     // Convert from Inverted CMYK (0..255) to RGB (0..255)
1307     const uint32_t iC = in[0];
1308     const uint32_t iM = in[1];
1309     const uint32_t iY = in[2];
1310     const uint32_t iK = in[3];
1311     out[0] = iC*iK/255;   // Red
1312     out[1] = iM*iK/255;   // Green
1313     out[2] = iY*iK/255;   // Blue
1314   }
1315 }
1316