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 #include "SurfacePipeFactory.h"
17 
18 #include "nspr.h"
19 #include "nsCRT.h"
20 #include "gfxColor.h"
21 
22 #include "jerror.h"
23 
24 #include "gfxPlatform.h"
25 #include "mozilla/EndianUtils.h"
26 #include "mozilla/gfx/Types.h"
27 #include "mozilla/Telemetry.h"
28 
29 extern "C" {
30 #include "iccjpeg.h"
31 }
32 
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 
39 static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
40                               int32_t aWidth);
41 
42 using mozilla::gfx::SurfaceFormat;
43 
44 namespace mozilla {
45 namespace image {
46 
47 static mozilla::LazyLogModule sJPEGLog("JPEGDecoder");
48 
49 static mozilla::LazyLogModule sJPEGDecoderAccountingLog(
50     "JPEGDecoderAccounting");
51 
GetICCProfile(struct jpeg_decompress_struct & info)52 static qcms_profile* GetICCProfile(struct jpeg_decompress_struct& info) {
53   JOCTET* profilebuf;
54   uint32_t profileLength;
55   qcms_profile* profile = nullptr;
56 
57   if (read_icc_profile(&info, &profilebuf, &profileLength)) {
58     profile = qcms_profile_from_memory(profilebuf, profileLength);
59     free(profilebuf);
60   }
61 
62   return profile;
63 }
64 
65 METHODDEF(void) init_source(j_decompress_ptr jd);
66 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr jd);
67 METHODDEF(void) skip_input_data(j_decompress_ptr jd, long num_bytes);
68 METHODDEF(void) term_source(j_decompress_ptr jd);
69 METHODDEF(void) my_error_exit(j_common_ptr cinfo);
70 
71 // Normal JFIF markers can't have more bytes than this.
72 #define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
73 
nsJPEGDecoder(RasterImage * aImage,Decoder::DecodeStyle aDecodeStyle)74 nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
75                              Decoder::DecodeStyle aDecodeStyle)
76     : Decoder(aImage),
77       mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
78                                       State::JPEG_DATA, SIZE_MAX),
79              Transition::TerminateSuccess()),
80       mProfile(nullptr),
81       mProfileLength(0),
82       mCMSLine(nullptr),
83       mDecodeStyle(aDecodeStyle) {
84   this->mErr.pub.error_exit = nullptr;
85   this->mErr.pub.emit_message = nullptr;
86   this->mErr.pub.output_message = nullptr;
87   this->mErr.pub.format_message = nullptr;
88   this->mErr.pub.reset_error_mgr = nullptr;
89   this->mErr.pub.msg_code = 0;
90   this->mErr.pub.trace_level = 0;
91   this->mErr.pub.num_warnings = 0;
92   this->mErr.pub.jpeg_message_table = nullptr;
93   this->mErr.pub.last_jpeg_message = 0;
94   this->mErr.pub.addon_message_table = nullptr;
95   this->mErr.pub.first_addon_message = 0;
96   this->mErr.pub.last_addon_message = 0;
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   MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
113           ("nsJPEGDecoder::nsJPEGDecoder: Creating JPEG decoder %p", this));
114 }
115 
~nsJPEGDecoder()116 nsJPEGDecoder::~nsJPEGDecoder() {
117   // Step 8: Release JPEG decompression object
118   mInfo.src = nullptr;
119   jpeg_destroy_decompress(&mInfo);
120 
121   free(mBackBuffer);
122   mBackBuffer = nullptr;
123 
124   delete[] mCMSLine;
125 
126   MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
127           ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p", this));
128 }
129 
SpeedHistogram() const130 Maybe<Telemetry::HistogramID> nsJPEGDecoder::SpeedHistogram() const {
131   return Some(Telemetry::IMAGE_DECODE_SPEED_JPEG);
132 }
133 
InitInternal()134 nsresult nsJPEGDecoder::InitInternal() {
135   // We set up the normal JPEG error routines, then override error_exit.
136   mInfo.err = jpeg_std_error(&mErr.pub);
137   //   mInfo.err = jpeg_std_error(&mErr.pub);
138   mErr.pub.error_exit = my_error_exit;
139   // Establish the setjmp return context for my_error_exit to use.
140   if (setjmp(mErr.setjmp_buffer)) {
141     // If we get here, the JPEG code has signaled an error, and initialization
142     // has failed.
143     return NS_ERROR_FAILURE;
144   }
145 
146   // Step 1: allocate and initialize JPEG decompression object
147   jpeg_create_decompress(&mInfo);
148   // Set the source manager
149   mInfo.src = &mSourceMgr;
150 
151   // Step 2: specify data source (eg, a file)
152 
153   // Setup callback functions.
154   mSourceMgr.init_source = init_source;
155   mSourceMgr.fill_input_buffer = fill_input_buffer;
156   mSourceMgr.skip_input_data = skip_input_data;
157   mSourceMgr.resync_to_restart = jpeg_resync_to_restart;
158   mSourceMgr.term_source = term_source;
159 
160   // Record app markers for ICC data
161   for (uint32_t m = 0; m < 16; m++) {
162     jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF);
163   }
164 
165   return NS_OK;
166 }
167 
FinishInternal()168 nsresult nsJPEGDecoder::FinishInternal() {
169   // If we're not in any sort of error case, force our state to JPEG_DONE.
170   if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
171       (mState != JPEG_ERROR) && !IsMetadataDecode()) {
172     mState = JPEG_DONE;
173   }
174 
175   return NS_OK;
176 }
177 
DoDecode(SourceBufferIterator & aIterator,IResumable * aOnResume)178 LexerResult nsJPEGDecoder::DoDecode(SourceBufferIterator& aIterator,
179                                     IResumable* aOnResume) {
180   MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
181 
182   return mLexer.Lex(aIterator, aOnResume,
183                     [=](State aState, const char* aData, size_t aLength) {
184                       switch (aState) {
185                         case State::JPEG_DATA:
186                           return ReadJPEGData(aData, aLength);
187                         case State::FINISHED_JPEG_DATA:
188                           return FinishedJPEGData();
189                       }
190                       MOZ_CRASH("Unknown State");
191                     });
192 }
193 
ReadJPEGData(const char * aData,size_t aLength)194 LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::ReadJPEGData(
195     const char* aData, size_t aLength) {
196   mSegment = reinterpret_cast<const JOCTET*>(aData);
197   mSegmentLen = aLength;
198 
199   // Return here if there is a fatal error within libjpeg.
200   nsresult error_code;
201   // This cast to nsresult makes sense because setjmp() returns whatever we
202   // passed to longjmp(), which was actually an nsresult.
203   if ((error_code = static_cast<nsresult>(setjmp(mErr.setjmp_buffer))) !=
204       NS_OK) {
205     if (error_code == NS_ERROR_FAILURE) {
206       // Error due to corrupt data. Make sure that we don't feed any more data
207       // to libjpeg-turbo.
208       mState = JPEG_SINK_NON_JPEG_TRAILER;
209       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
210               ("} (setjmp returned NS_ERROR_FAILURE)"));
211     } else {
212       // Error for another reason. (Possibly OOM.)
213       mState = JPEG_ERROR;
214       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
215               ("} (setjmp returned an error)"));
216     }
217 
218     return Transition::TerminateFailure();
219   }
220 
221   MOZ_LOG(sJPEGLog, LogLevel::Debug,
222           ("[this=%p] nsJPEGDecoder::Write -- processing JPEG data\n", this));
223 
224   switch (mState) {
225     case JPEG_HEADER: {
226       LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
227                 "nsJPEGDecoder::Write -- entering JPEG_HEADER"
228                 " case");
229 
230       // Step 3: read file parameters with jpeg_read_header()
231       if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) {
232         MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
233                 ("} (JPEG_SUSPENDED)"));
234         return Transition::ContinueUnbuffered(
235             State::JPEG_DATA);  // I/O suspension
236       }
237 
238       // Post our size to the superclass
239       EXIFData exif = ReadExifData();
240       PostSize(mInfo.image_width, mInfo.image_height, exif.orientation,
241                exif.resolution);
242       if (HasError()) {
243         // Setting the size led to an error.
244         mState = JPEG_ERROR;
245         return Transition::TerminateFailure();
246       }
247 
248       // If we're doing a metadata decode, we're done.
249       if (IsMetadataDecode()) {
250         return Transition::TerminateSuccess();
251       }
252 
253       // We're doing a full decode.
254       switch (mInfo.jpeg_color_space) {
255         case JCS_GRAYSCALE:
256         case JCS_RGB:
257         case JCS_YCbCr:
258           // By default, we will output directly to BGRA. If we need to apply
259           // special color transforms, this may change.
260 #if MOZ_BIG_ENDIAN()
261           mInfo.out_color_space = MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB;
262 #else
263           switch (SurfaceFormat::OS_RGBX) {
264             case SurfaceFormat::B8G8R8X8:
265               mInfo.out_color_space = JCS_EXT_BGRX;
266               break;
267             case SurfaceFormat::X8R8G8B8:
268               mInfo.out_color_space = JCS_EXT_XRGB;
269               break;
270             case SurfaceFormat::R8G8B8X8:
271               mInfo.out_color_space = JCS_EXT_RGBX;
272               break;
273             default:
274               mState = JPEG_ERROR;
275               return Transition::TerminateFailure();
276           }
277 #endif
278           break;
279         case JCS_CMYK:
280         case JCS_YCCK:
281           // libjpeg can convert from YCCK to CMYK, but not to XRGB.
282           mInfo.out_color_space = JCS_CMYK;
283           break;
284         default:
285           mState = JPEG_ERROR;
286           MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
287                   ("} (unknown colorspace (3))"));
288           return Transition::TerminateFailure();
289       }
290 
291       if (mCMSMode != CMSMode::Off) {
292         if ((mInProfile = GetICCProfile(mInfo)) != nullptr &&
293             GetCMSOutputProfile()) {
294           uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
295 
296           qcms_data_type outputType = gfxPlatform::GetCMSOSRGBAType();
297           Maybe<qcms_data_type> inputType;
298           if (profileSpace == icSigRgbData) {
299             // We can always color manage RGB profiles since it happens at the
300             // end of the pipeline.
301             inputType.emplace(outputType);
302           } else if (profileSpace == icSigGrayData &&
303                      mInfo.jpeg_color_space == JCS_GRAYSCALE) {
304             // We can only color manage gray profiles if the original color
305             // space is grayscale. This means we must downscale after color
306             // management since the downscaler assumes BGRA.
307             mInfo.out_color_space = JCS_GRAYSCALE;
308             inputType.emplace(QCMS_DATA_GRAY_8);
309           }
310 
311 #if 0
312           // We don't currently support CMYK profiles. The following
313           // code dealt with lcms types. Add something like this
314           // back when we gain support for CMYK.
315 
316           // Adobe Photoshop writes YCCK/CMYK files with inverted data
317           if (mInfo.out_color_space == JCS_CMYK) {
318             type |= FLAVOR_SH(mInfo.saw_Adobe_marker ? 1 : 0);
319           }
320 #endif
321 
322           if (inputType) {
323             // Calculate rendering intent.
324             int intent = gfxPlatform::GetRenderingIntent();
325             if (intent == -1) {
326               intent = qcms_profile_get_rendering_intent(mInProfile);
327             }
328 
329             // Create the color management transform.
330             mTransform = qcms_transform_create(mInProfile, *inputType,
331                                                GetCMSOutputProfile(),
332                                                outputType, (qcms_intent)intent);
333           }
334         } else if (mCMSMode == CMSMode::All) {
335           mTransform = GetCMSsRGBTransform(SurfaceFormat::OS_RGBX);
336         }
337       }
338 
339       // We don't want to use the pipe buffers directly because we don't want
340       // any reads on non-BGRA formatted data.
341       if (mInfo.out_color_space == JCS_GRAYSCALE ||
342           mInfo.out_color_space == JCS_CMYK) {
343         mCMSLine = new (std::nothrow) uint32_t[mInfo.image_width];
344         if (!mCMSLine) {
345           mState = JPEG_ERROR;
346           MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
347                   ("} (could allocate buffer for color conversion)"));
348           return Transition::TerminateFailure();
349         }
350       }
351 
352       // Don't allocate a giant and superfluous memory buffer
353       // when not doing a progressive decode.
354       mInfo.buffered_image =
355           mDecodeStyle == PROGRESSIVE && jpeg_has_multiple_scans(&mInfo);
356 
357       /* Used to set up image size so arrays can be allocated */
358       jpeg_calc_output_dimensions(&mInfo);
359 
360       // We handle the transform outside the pipeline if we are outputting in
361       // grayscale, because the pipeline wants BGRA pixels, particularly the
362       // downscaling filter, so we can't handle it after downscaling as would
363       // be optimal.
364       qcms_transform* pipeTransform =
365           mInfo.out_color_space != JCS_GRAYSCALE ? mTransform : nullptr;
366 
367       Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateReorientSurfacePipe(
368           this, Size(), OutputSize(), SurfaceFormat::OS_RGBX, pipeTransform,
369           GetOrientation());
370       if (!pipe) {
371         mState = JPEG_ERROR;
372         MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
373                 ("} (could not initialize surface pipe)"));
374         return Transition::TerminateFailure();
375       }
376 
377       mPipe = std::move(*pipe);
378 
379       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
380               ("        JPEGDecoderAccounting: nsJPEGDecoder::"
381                "Write -- created image frame with %ux%u pixels",
382                mInfo.image_width, mInfo.image_height));
383 
384       mState = JPEG_START_DECOMPRESS;
385       [[fallthrough]];  // to start decompressing.
386     }
387 
388     case JPEG_START_DECOMPRESS: {
389       LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
390                 "nsJPEGDecoder::Write -- entering"
391                 " JPEG_START_DECOMPRESS case");
392       // Step 4: set parameters for decompression
393 
394       // FIXME -- Should reset dct_method and dither mode
395       // for final pass of progressive JPEG
396 
397       mInfo.dct_method = JDCT_ISLOW;
398       mInfo.dither_mode = JDITHER_FS;
399       mInfo.do_fancy_upsampling = TRUE;
400       mInfo.enable_2pass_quant = FALSE;
401       mInfo.do_block_smoothing = TRUE;
402 
403       // Step 5: Start decompressor
404       if (jpeg_start_decompress(&mInfo) == FALSE) {
405         MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
406                 ("} (I/O suspension after jpeg_start_decompress())"));
407         return Transition::ContinueUnbuffered(
408             State::JPEG_DATA);  // I/O suspension
409       }
410 
411       // If this is a progressive JPEG ...
412       mState = mInfo.buffered_image ? JPEG_DECOMPRESS_PROGRESSIVE
413                                     : JPEG_DECOMPRESS_SEQUENTIAL;
414       [[fallthrough]];  // to decompress sequential JPEG.
415     }
416 
417     case JPEG_DECOMPRESS_SEQUENTIAL: {
418       if (mState == JPEG_DECOMPRESS_SEQUENTIAL) {
419         LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
420                   "nsJPEGDecoder::Write -- "
421                   "JPEG_DECOMPRESS_SEQUENTIAL case");
422 
423         switch (OutputScanlines()) {
424           case WriteState::NEED_MORE_DATA:
425             MOZ_LOG(
426                 sJPEGDecoderAccountingLog, LogLevel::Debug,
427                 ("} (I/O suspension after OutputScanlines() - SEQUENTIAL)"));
428             return Transition::ContinueUnbuffered(
429                 State::JPEG_DATA);  // I/O suspension
430           case WriteState::FINISHED:
431             NS_ASSERTION(mInfo.output_scanline == mInfo.output_height,
432                          "We didn't process all of the data!");
433             mState = JPEG_DONE;
434             break;
435           case WriteState::FAILURE:
436             mState = JPEG_ERROR;
437             MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
438                     ("} (Error in pipeline from OutputScalines())"));
439             return Transition::TerminateFailure();
440         }
441       }
442       [[fallthrough]];  // to decompress progressive JPEG.
443     }
444 
445     case JPEG_DECOMPRESS_PROGRESSIVE: {
446       if (mState == JPEG_DECOMPRESS_PROGRESSIVE) {
447         LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
448                   "nsJPEGDecoder::Write -- JPEG_DECOMPRESS_PROGRESSIVE case");
449         auto AllComponentsSeen = [](jpeg_decompress_struct& mInfo) {
450           bool all_components_seen = true;
451           if (mInfo.coef_bits) {
452             for (int c = 0; c < mInfo.num_components; ++c) {
453               bool current_component_seen = mInfo.coef_bits[c][0] != -1;
454               all_components_seen &= current_component_seen;
455             }
456           }
457           return all_components_seen;
458         };
459         int status;
460         int scan_to_display_first = 0;
461         bool all_components_seen;
462         all_components_seen = AllComponentsSeen(mInfo);
463         if (all_components_seen) {
464           scan_to_display_first = mInfo.input_scan_number;
465         }
466 
467         do {
468           status = jpeg_consume_input(&mInfo);
469 
470           if (status == JPEG_REACHED_SOS || status == JPEG_REACHED_EOI ||
471               status == JPEG_SUSPENDED) {
472             // record the first scan where all components are present
473             all_components_seen = AllComponentsSeen(mInfo);
474             if (!scan_to_display_first && all_components_seen) {
475               scan_to_display_first = mInfo.input_scan_number;
476             }
477           }
478         } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_EOI));
479 
480         if (!all_components_seen) {
481           return Transition::ContinueUnbuffered(
482               State::JPEG_DATA);  // I/O suspension
483         }
484         // make sure we never try to access the non-exsitent scan 0
485         if (!scan_to_display_first) {
486           scan_to_display_first = 1;
487         }
488         while (mState != JPEG_DONE) {
489           if (mInfo.output_scanline == 0) {
490             int scan = mInfo.input_scan_number;
491 
492             // if we haven't displayed anything yet (output_scan_number==0)
493             // and we have enough data for a complete scan, force output
494             // of the last full scan,  but only if this last scan has seen
495             // DC data from all components
496             if ((mInfo.output_scan_number == 0) &&
497                 (scan > scan_to_display_first) &&
498                 (status != JPEG_REACHED_EOI)) {
499               scan--;
500             }
501             MOZ_ASSERT(scan > 0, "scan number to small!");
502             if (!jpeg_start_output(&mInfo, scan)) {
503               MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
504                       ("} (I/O suspension after jpeg_start_output() -"
505                        " PROGRESSIVE)"));
506               return Transition::ContinueUnbuffered(
507                   State::JPEG_DATA);  // I/O suspension
508             }
509           }
510 
511           if (mInfo.output_scanline == 0xffffff) {
512             mInfo.output_scanline = 0;
513           }
514 
515           switch (OutputScanlines()) {
516             case WriteState::NEED_MORE_DATA:
517               if (mInfo.output_scanline == 0) {
518                 // didn't manage to read any lines - flag so we don't call
519                 // jpeg_start_output() multiple times for the same scan
520                 mInfo.output_scanline = 0xffffff;
521               }
522               MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
523                       ("} (I/O suspension after OutputScanlines() - "
524                        "PROGRESSIVE)"));
525               return Transition::ContinueUnbuffered(
526                   State::JPEG_DATA);  // I/O suspension
527             case WriteState::FINISHED:
528               NS_ASSERTION(mInfo.output_scanline == mInfo.output_height,
529                            "We didn't process all of the data!");
530 
531               if (!jpeg_finish_output(&mInfo)) {
532                 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
533                         ("} (I/O suspension after jpeg_finish_output() -"
534                          " PROGRESSIVE)"));
535                 return Transition::ContinueUnbuffered(
536                     State::JPEG_DATA);  // I/O suspension
537               }
538 
539               if (jpeg_input_complete(&mInfo) &&
540                   (mInfo.input_scan_number == mInfo.output_scan_number)) {
541                 mState = JPEG_DONE;
542               } else {
543                 mInfo.output_scanline = 0;
544                 mPipe.ResetToFirstRow();
545               }
546               break;
547             case WriteState::FAILURE:
548               mState = JPEG_ERROR;
549               MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
550                       ("} (Error in pipeline from OutputScalines())"));
551               return Transition::TerminateFailure();
552           }
553         }
554       }
555       [[fallthrough]];  // to finish decompressing.
556     }
557 
558     case JPEG_DONE: {
559       LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
560                 "nsJPEGDecoder::ProcessData -- entering"
561                 " JPEG_DONE case");
562 
563       // Step 7: Finish decompression
564 
565       if (jpeg_finish_decompress(&mInfo) == FALSE) {
566         MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
567                 ("} (I/O suspension after jpeg_finish_decompress() - DONE)"));
568         return Transition::ContinueUnbuffered(
569             State::JPEG_DATA);  // I/O suspension
570       }
571 
572       // Make sure we don't feed any more data to libjpeg-turbo.
573       mState = JPEG_SINK_NON_JPEG_TRAILER;
574 
575       // We're done.
576       return Transition::TerminateSuccess();
577     }
578     case JPEG_SINK_NON_JPEG_TRAILER:
579       MOZ_LOG(sJPEGLog, LogLevel::Debug,
580               ("[this=%p] nsJPEGDecoder::ProcessData -- entering"
581                " JPEG_SINK_NON_JPEG_TRAILER case\n",
582                this));
583 
584       MOZ_ASSERT_UNREACHABLE(
585           "Should stop getting data after entering state "
586           "JPEG_SINK_NON_JPEG_TRAILER");
587 
588       return Transition::TerminateSuccess();
589 
590     case JPEG_ERROR:
591       MOZ_ASSERT_UNREACHABLE(
592           "Should stop getting data after entering state "
593           "JPEG_ERROR");
594 
595       return Transition::TerminateFailure();
596   }
597 
598   MOZ_ASSERT_UNREACHABLE("Escaped the JPEG decoder state machine");
599   return Transition::TerminateFailure();
600 }  // namespace image
601 
FinishedJPEGData()602 LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::FinishedJPEGData() {
603   // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read
604   // all that data something is really wrong.
605   MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
606   return Transition::TerminateFailure();
607 }
608 
ReadExifData() const609 EXIFData nsJPEGDecoder::ReadExifData() const {
610   jpeg_saved_marker_ptr marker;
611 
612   // Locate the APP1 marker, where EXIF data is stored, in the marker list.
613   for (marker = mInfo.marker_list; marker != nullptr; marker = marker->next) {
614     if (marker->marker == JPEG_APP0 + 1) {
615       break;
616     }
617   }
618 
619   // If we're at the end of the list, there's no EXIF data.
620   if (!marker) {
621     return EXIFData();
622   }
623 
624   return EXIFParser::Parse(marker->data,
625                            static_cast<uint32_t>(marker->data_length),
626                            gfx::IntSize(mInfo.image_width, mInfo.image_height));
627 }
628 
NotifyDone()629 void nsJPEGDecoder::NotifyDone() {
630   PostFrameStop(Opacity::FULLY_OPAQUE);
631   PostDecodeDone();
632 }
633 
OutputScanlines()634 WriteState nsJPEGDecoder::OutputScanlines() {
635   auto result = mPipe.WritePixelBlocks<uint32_t>(
636       [&](uint32_t* aPixelBlock, int32_t aBlockSize) {
637         JSAMPROW sampleRow = (JSAMPROW)(mCMSLine ? mCMSLine : aPixelBlock);
638         if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) {
639           return MakeTuple(/* aWritten */ 0, Some(WriteState::NEED_MORE_DATA));
640         }
641 
642         switch (mInfo.out_color_space) {
643           default:
644             // Already outputted directly to aPixelBlock as BGRA.
645             MOZ_ASSERT(!mCMSLine);
646             break;
647           case JCS_GRAYSCALE:
648             // The transform here does both color management, and converts the
649             // pixels from grayscale to BGRA. This is why we do it here, instead
650             // of using ColorManagementFilter in the SurfacePipe, because the
651             // other filters (e.g. DownscalingFilter) require BGRA pixels.
652             MOZ_ASSERT(mCMSLine);
653             qcms_transform_data(mTransform, mCMSLine, aPixelBlock,
654                                 mInfo.output_width);
655             break;
656           case JCS_CMYK:
657             // Convert from CMYK to BGRA
658             MOZ_ASSERT(mCMSLine);
659             cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize);
660             break;
661         }
662 
663         return MakeTuple(aBlockSize, Maybe<WriteState>());
664       });
665 
666   Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
667   if (invalidRect) {
668     PostInvalidation(invalidRect->mInputSpaceRect,
669                      Some(invalidRect->mOutputSpaceRect));
670   }
671 
672   return result;
673 }
674 
675 // Override the standard error method in the IJG JPEG decoder code.
676 METHODDEF(void)
my_error_exit(j_common_ptr cinfo)677 my_error_exit(j_common_ptr cinfo) {
678   decoder_error_mgr* err = (decoder_error_mgr*)cinfo->err;
679 
680   // Convert error to a browser error code
681   nsresult error_code = err->pub.msg_code == JERR_OUT_OF_MEMORY
682                             ? NS_ERROR_OUT_OF_MEMORY
683                             : NS_ERROR_FAILURE;
684 
685 #ifdef DEBUG
686   char buffer[JMSG_LENGTH_MAX];
687 
688   // Create the message
689   (*err->pub.format_message)(cinfo, buffer);
690 
691   fprintf(stderr, "JPEG decoding error:\n%s\n", buffer);
692 #endif
693 
694   // Return control to the setjmp point.  We pass an nsresult masquerading as
695   // an int, which works because the setjmp() caller casts it back.
696   longjmp(err->setjmp_buffer, static_cast<int>(error_code));
697 }
698 
699 /*******************************************************************************
700  * This is the callback routine from the IJG JPEG library used to supply new
701  * data to the decompressor when its input buffer is exhausted.  It juggles
702  * multiple buffers in an attempt to avoid unnecessary copying of input data.
703  *
704  * (A simpler scheme is possible: It's much easier to use only a single
705  * buffer; when fill_input_buffer() is called, move any unconsumed data
706  * (beyond the current pointer/count) down to the beginning of this buffer and
707  * then load new data into the remaining buffer space.  This approach requires
708  * a little more data copying but is far easier to get right.)
709  *
710  * At any one time, the JPEG decompressor is either reading from the necko
711  * input buffer, which is volatile across top-level calls to the IJG library,
712  * or the "backtrack" buffer.  The backtrack buffer contains the remaining
713  * unconsumed data from the necko buffer after parsing was suspended due
714  * to insufficient data in some previous call to the IJG library.
715  *
716  * When suspending, the decompressor will back up to a convenient restart
717  * point (typically the start of the current MCU). The variables
718  * next_input_byte & bytes_in_buffer indicate where the restart point will be
719  * if the current call returns FALSE.  Data beyond this point must be
720  * rescanned after resumption, so it must be preserved in case the decompressor
721  * decides to backtrack.
722  *
723  * Returns:
724  *  TRUE if additional data is available, FALSE if no data present and
725  *   the JPEG library should therefore suspend processing of input stream
726  ******************************************************************************/
727 
728 /******************************************************************************/
729 /* data source manager method                                                 */
730 /******************************************************************************/
731 
732 /******************************************************************************/
733 /* data source manager method
734         Initialize source.  This is called by jpeg_read_header() before any
735         data is actually read.  May leave
736         bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
737         will occur immediately).
738 */
739 METHODDEF(void)
init_source(j_decompress_ptr jd)740 init_source(j_decompress_ptr jd) {}
741 
742 /******************************************************************************/
743 /* data source manager method
744         Skip num_bytes worth of data.  The buffer pointer and count should
745         be advanced over num_bytes input bytes, refilling the buffer as
746         needed.  This is used to skip over a potentially large amount of
747         uninteresting data (such as an APPn marker).  In some applications
748         it may be possible to optimize away the reading of the skipped data,
749         but it's not clear that being smart is worth much trouble; large
750         skips are uncommon.  bytes_in_buffer may be zero on return.
751         A zero or negative skip count should be treated as a no-op.
752 */
753 METHODDEF(void)
skip_input_data(j_decompress_ptr jd,long num_bytes)754 skip_input_data(j_decompress_ptr jd, long num_bytes) {
755   struct jpeg_source_mgr* src = jd->src;
756   nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
757 
758   if (num_bytes > (long)src->bytes_in_buffer) {
759     // Can't skip it all right now until we get more data from
760     // network stream. Set things up so that fill_input_buffer
761     // will skip remaining amount.
762     decoder->mBytesToSkip = (size_t)num_bytes - src->bytes_in_buffer;
763     src->next_input_byte += src->bytes_in_buffer;
764     src->bytes_in_buffer = 0;
765 
766   } else {
767     // Simple case. Just advance buffer pointer
768 
769     src->bytes_in_buffer -= (size_t)num_bytes;
770     src->next_input_byte += num_bytes;
771   }
772 }
773 
774 /******************************************************************************/
775 /* data source manager method
776         This is called whenever bytes_in_buffer has reached zero and more
777         data is wanted.  In typical applications, it should read fresh data
778         into the buffer (ignoring the current state of next_input_byte and
779         bytes_in_buffer), reset the pointer & count to the start of the
780         buffer, and return TRUE indicating that the buffer has been reloaded.
781         It is not necessary to fill the buffer entirely, only to obtain at
782         least one more byte.  bytes_in_buffer MUST be set to a positive value
783         if TRUE is returned.  A FALSE return should only be used when I/O
784         suspension is desired.
785 */
786 METHODDEF(boolean)
fill_input_buffer(j_decompress_ptr jd)787 fill_input_buffer(j_decompress_ptr jd) {
788   struct jpeg_source_mgr* src = jd->src;
789   nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
790 
791   if (decoder->mReading) {
792     const JOCTET* new_buffer = decoder->mSegment;
793     uint32_t new_buflen = decoder->mSegmentLen;
794 
795     if (!new_buffer || new_buflen == 0) {
796       return false;  // suspend
797     }
798 
799     decoder->mSegmentLen = 0;
800 
801     if (decoder->mBytesToSkip) {
802       if (decoder->mBytesToSkip < new_buflen) {
803         // All done skipping bytes; Return what's left.
804         new_buffer += decoder->mBytesToSkip;
805         new_buflen -= decoder->mBytesToSkip;
806         decoder->mBytesToSkip = 0;
807       } else {
808         // Still need to skip some more data in the future
809         decoder->mBytesToSkip -= (size_t)new_buflen;
810         return false;  // suspend
811       }
812     }
813 
814     decoder->mBackBufferUnreadLen = src->bytes_in_buffer;
815 
816     src->next_input_byte = new_buffer;
817     src->bytes_in_buffer = (size_t)new_buflen;
818     decoder->mReading = false;
819 
820     return true;
821   }
822 
823   if (src->next_input_byte != decoder->mSegment) {
824     // Backtrack data has been permanently consumed.
825     decoder->mBackBufferUnreadLen = 0;
826     decoder->mBackBufferLen = 0;
827   }
828 
829   // Save remainder of netlib buffer in backtrack buffer
830   const uint32_t new_backtrack_buflen =
831       src->bytes_in_buffer + decoder->mBackBufferLen;
832 
833   // Make sure backtrack buffer is big enough to hold new data.
834   if (decoder->mBackBufferSize < new_backtrack_buflen) {
835     // Check for malformed MARKER segment lengths, before allocating space
836     // for it
837     if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
838       my_error_exit((j_common_ptr)(&decoder->mInfo));
839     }
840 
841     // Round up to multiple of 256 bytes.
842     const size_t roundup_buflen = ((new_backtrack_buflen + 255) >> 8) << 8;
843     JOCTET* buf = (JOCTET*)realloc(decoder->mBackBuffer, roundup_buflen);
844     // Check for OOM
845     if (!buf) {
846       decoder->mInfo.err->msg_code = JERR_OUT_OF_MEMORY;
847       my_error_exit((j_common_ptr)(&decoder->mInfo));
848     }
849     decoder->mBackBuffer = buf;
850     decoder->mBackBufferSize = roundup_buflen;
851   }
852 
853   // Ensure we actually have a backtrack buffer. Without it, then we know that
854   // there is no data to copy and bytes_in_buffer is already zero.
855   if (decoder->mBackBuffer) {
856     // Copy remainder of netlib segment into backtrack buffer.
857     memmove(decoder->mBackBuffer + decoder->mBackBufferLen,
858             src->next_input_byte, src->bytes_in_buffer);
859   } else {
860     MOZ_ASSERT(src->bytes_in_buffer == 0);
861     MOZ_ASSERT(decoder->mBackBufferLen == 0);
862     MOZ_ASSERT(decoder->mBackBufferUnreadLen == 0);
863   }
864 
865   // Point to start of data to be rescanned.
866   src->next_input_byte = decoder->mBackBuffer + decoder->mBackBufferLen -
867                          decoder->mBackBufferUnreadLen;
868   src->bytes_in_buffer += decoder->mBackBufferUnreadLen;
869   decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
870   decoder->mReading = true;
871 
872   return false;
873 }
874 
875 /******************************************************************************/
876 /* data source manager method */
877 /*
878  * Terminate source --- called by jpeg_finish_decompress() after all
879  * data has been read to clean up JPEG source manager. NOT called by
880  * jpeg_abort() or jpeg_destroy().
881  */
882 METHODDEF(void)
term_source(j_decompress_ptr jd)883 term_source(j_decompress_ptr jd) {
884   nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
885 
886   // This function shouldn't be called if we ran into an error we didn't
887   // recover from.
888   MOZ_ASSERT(decoder->mState != JPEG_ERROR,
889              "Calling term_source on a JPEG with mState == JPEG_ERROR!");
890 
891   // Notify using a helper method to get around protectedness issues.
892   decoder->NotifyDone();
893 }
894 
895 }  // namespace image
896 }  // namespace mozilla
897 
898 ///*************** Inverted CMYK -> RGB conversion *************************
899 /// Input is (Inverted) CMYK stored as 4 bytes per pixel.
900 /// Output is RGB stored as 3 bytes per pixel.
901 /// @param aInput Points to row buffer containing the CMYK bytes for each pixel
902 ///               in the row.
903 /// @param aOutput Points to row buffer to write BGRA to.
904 /// @param aWidth Number of pixels in the row.
cmyk_convert_bgra(uint32_t * aInput,uint32_t * aOutput,int32_t aWidth)905 static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput,
906                               int32_t aWidth) {
907   uint8_t* input = reinterpret_cast<uint8_t*>(aInput);
908 
909   for (int32_t i = 0; i < aWidth; ++i) {
910     // Source is 'Inverted CMYK', output is RGB.
911     // See: http://www.easyrgb.com/math.php?MATH=M12#text12
912     // Or:  http://www.ilkeratalay.com/colorspacesfaq.php#rgb
913 
914     // From CMYK to CMY
915     // C = ( C * ( 1 - K ) + K )
916     // M = ( M * ( 1 - K ) + K )
917     // Y = ( Y * ( 1 - K ) + K )
918 
919     // From Inverted CMYK to CMY is thus:
920     // C = ( (1-iC) * (1 - (1-iK)) + (1-iK) ) => 1 - iC*iK
921     // Same for M and Y
922 
923     // Convert from CMY (0..1) to RGB (0..1)
924     // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
925     // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
926     // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
927 
928     // Convert from Inverted CMYK (0..255) to RGB (0..255)
929     const uint32_t iC = input[0];
930     const uint32_t iM = input[1];
931     const uint32_t iY = input[2];
932     const uint32_t iK = input[3];
933 
934     const uint8_t r = iC * iK / 255;
935     const uint8_t g = iM * iK / 255;
936     const uint8_t b = iY * iK / 255;
937 
938     *aOutput++ = (0xFF << mozilla::gfx::SurfaceFormatBit::OS_A) |
939                  (r << mozilla::gfx::SurfaceFormatBit::OS_R) |
940                  (g << mozilla::gfx::SurfaceFormatBit::OS_G) |
941                  (b << mozilla::gfx::SurfaceFormatBit::OS_B);
942     input += 4;
943   }
944 }
945