DLLEXPORT int GET_NAME()

in turbojpeg-mp.c [141:280]


DLLEXPORT int GET_NAME(tj3Decompress, BITS_IN_JSAMPLE)
  (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize,
   _JSAMPLE *dstBuf, int pitch, int pixelFormat)
{
  static const char FUNCTION_NAME[] =
    GET_STRING(tj3Decompress, BITS_IN_JSAMPLE);
  _JSAMPROW *row_pointer = NULL;
  int croppedHeight, i, retval = 0;
#if BITS_IN_JSAMPLE != 16
  int scaledWidth;
#endif
  struct my_progress_mgr progress;

  GET_DINSTANCE(handle);
  if ((this->init & DECOMPRESS) == 0)
    THROW("Instance has not been initialized for decompression");

  if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 ||
      pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
    THROW("Invalid argument");

  if (this->scanLimit) {
    memset(&progress, 0, sizeof(struct my_progress_mgr));
    progress.pub.progress_monitor = my_progress_monitor;
    progress.this = this;
    dinfo->progress = &progress.pub;
  } else
    dinfo->progress = NULL;

  dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L;

  if (setjmp(this->jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error. */
    retval = -1;  goto bailout;
  }

  if (dinfo->global_state <= DSTATE_INHEADER) {
    jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
    jpeg_read_header(dinfo, TRUE);
  }
  setDecompParameters(this);
  if (this->maxPixels &&
      (unsigned long long)this->jpegWidth * this->jpegHeight >
      (unsigned long long)this->maxPixels)
    THROW("Image is too large");
  this->dinfo.out_color_space = pf2cs[pixelFormat];
#if BITS_IN_JSAMPLE != 16
  scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor);
#endif
  dinfo->do_fancy_upsampling = !this->fastUpsample;
  this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW;

  dinfo->scale_num = this->scalingFactor.num;
  dinfo->scale_denom = this->scalingFactor.denom;

  jpeg_start_decompress(dinfo);

#if BITS_IN_JSAMPLE != 16
  if (this->croppingRegion.x != 0 ||
      (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) {
    JDIMENSION crop_x = this->croppingRegion.x;
    JDIMENSION crop_w = this->croppingRegion.w;

    _jpeg_crop_scanline(dinfo, &crop_x, &crop_w);
    if ((int)crop_x != this->croppingRegion.x)
      THROWI("Unexplained mismatch between specified (%d) and\n"
             "actual (%d) cropping region left boundary",
             this->croppingRegion.x, (int)crop_x);
    if ((int)crop_w != this->croppingRegion.w)
      THROWI("Unexplained mismatch between specified (%d) and\n"
             "actual (%d) cropping region width",
             this->croppingRegion.w, (int)crop_w);
  }
#endif

  if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat];

  croppedHeight = dinfo->output_height;
#if BITS_IN_JSAMPLE != 16
  if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0)
    croppedHeight = this->croppingRegion.h;
#endif
  if ((row_pointer =
       (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL)
    THROW("Memory allocation failure");
  if (setjmp(this->jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error. */
    retval = -1;  goto bailout;
  }
  for (i = 0; i < (int)croppedHeight; i++) {
    if (this->bottomUp)
      row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch];
    else
      row_pointer[i] = &dstBuf[i * (size_t)pitch];
  }

#if BITS_IN_JSAMPLE != 16
  if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) {
    if (this->croppingRegion.y != 0) {
      JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y);

      if ((int)lines != this->croppingRegion.y)
        THROWI("Unexplained mismatch between specified (%d) and\n"
               "actual (%d) cropping region upper boundary",
               this->croppingRegion.y, (int)lines);
    }
    while ((int)dinfo->output_scanline <
           this->croppingRegion.y + this->croppingRegion.h)
      _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline -
                                               this->croppingRegion.y],
                           this->croppingRegion.y + this->croppingRegion.h -
                           dinfo->output_scanline);
    if (this->croppingRegion.y + this->croppingRegion.h !=
        (int)dinfo->output_height) {
      JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height -
                                                     this->croppingRegion.y -
                                                     this->croppingRegion.h);

      if (lines != dinfo->output_height - this->croppingRegion.y -
                   this->croppingRegion.h)
        THROWI("Unexplained mismatch between specified (%d) and\n"
               "actual (%d) cropping region lower boundary",
               this->croppingRegion.y + this->croppingRegion.h,
               (int)(dinfo->output_height - lines));
    }
  } else
#endif
  {
    while (dinfo->output_scanline < dinfo->output_height)
      _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline],
                           dinfo->output_height - dinfo->output_scanline);
  }
  jpeg_finish_decompress(dinfo);

bailout:
  if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
  free(row_pointer);
  if (this->jerr.warning) retval = -1;
  return retval;
}