PageRenderTime 127ms CodeModel.GetById 17ms app.highlight 97ms RepoModel.GetById 2ms app.codeStats 0ms

/image/decoders/nsJPEGDecoder.cpp

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