tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsJPEGDecoder.cpp (37660B)


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