static int decomp()

in tjbench.c [173:372]


static int decomp(unsigned char **jpegBufs, size_t *jpegSizes, void *dstBuf,
                  int w, int h, int subsamp, int jpegQual, char *fileName,
                  int tilew, int tileh)
{
  char tempStr[1024], sizeStr[24] = "\0", qualStr[16] = "\0";
  FILE *file = NULL;
  tjhandle handle = NULL;
  int i, row, col, iter = 0, dstBufAlloc = 0, retval = 0;
  double elapsed, elapsedDecode;
  int ps = tjPixelSize[pf];
  int scaledw, scaledh, pitch;
  int ntilesw = (w + tilew - 1) / tilew, ntilesh = (h + tileh - 1) / tileh;
  unsigned char *dstPtr, *dstPtr2, *yuvBuf = NULL;

  if (lossless) sf = TJUNSCALED;

  scaledw = TJSCALED(w, sf);
  scaledh = TJSCALED(h, sf);

  if (jpegQual > 0) {
    SNPRINTF(qualStr, 16, "_%s%d", lossless ? "PSV" : "Q", jpegQual);
    qualStr[15] = 0;
  }

  if ((handle = tj3Init(TJINIT_DECOMPRESS)) == NULL)
    THROW_TJG();
  if (tj3Set(handle, TJPARAM_STOPONWARNING, stopOnWarning) == -1)
    THROW_TJ();
  if (tj3Set(handle, TJPARAM_BOTTOMUP, bottomUp) == -1)
    THROW_TJ();
  if (tj3Set(handle, TJPARAM_FASTUPSAMPLE, fastUpsample) == -1)
    THROW_TJ();
  if (tj3Set(handle, TJPARAM_FASTDCT, fastDCT) == -1)
    THROW_TJ();
  if (tj3Set(handle, TJPARAM_SCANLIMIT, limitScans ? 500 : 0) == -1)
    THROW_TJ();
  if (tj3Set(handle, TJPARAM_MAXMEMORY, maxMemory) == -1)
    THROW_TJ();
  if (tj3Set(handle, TJPARAM_MAXPIXELS, maxPixels) == -1)
    THROW_TJ();

  if (IS_CROPPED(cr)) {
    if (tj3DecompressHeader(handle, jpegBufs[0], jpegSizes[0]) == -1)
      THROW_TJ();
  }
  if (tj3SetScalingFactor(handle, sf) == -1)
    THROW_TJ();
  if (tj3SetCroppingRegion(handle, cr) == -1)
    THROW_TJ();
  if (IS_CROPPED(cr)) {
    scaledw = cr.w ? cr.w : scaledw - cr.x;
    scaledh = cr.h ? cr.h : scaledh - cr.y;
  }
  pitch = scaledw * ps;

  if (dstBuf == NULL) {
#if ULLONG_MAX > SIZE_MAX
    if ((unsigned long long)pitch * (unsigned long long)scaledh *
        (unsigned long long)sampleSize > (unsigned long long)((size_t)-1))
      THROW("allocating destination buffer", "Image is too large");
#endif
    if ((dstBuf = malloc((size_t)pitch * scaledh * sampleSize)) == NULL)
      THROW_UNIX("allocating destination buffer");
    dstBufAlloc = 1;
  }

  /* Set the destination buffer to gray so we know whether the decompressor
     attempted to write to it */
  if (precision == 8)
    memset((unsigned char *)dstBuf, 127, (size_t)pitch * scaledh);
  else if (precision == 12) {
    for (i = 0; i < pitch * scaledh; i++)
      ((short *)dstBuf)[i] = (short)2047;
  } else {
    for (i = 0; i < pitch * scaledh; i++)
      ((unsigned short *)dstBuf)[i] = (unsigned short)32767;
  }

  if (doYUV) {
    int width = doTile ? tilew : scaledw;
    int height = doTile ? tileh : scaledh;
    size_t yuvSize = tj3YUVBufSize(width, yuvAlign, height, subsamp);

    if (yuvSize == 0)
      THROW_TJG();
    if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
      THROW_UNIX("allocating YUV buffer");
    memset(yuvBuf, 127, yuvSize);
  }

  /* Benchmark */
  iter = -1;
  elapsed = elapsedDecode = 0.;
  while (1) {
    int tile = 0;
    double start = getTime();

    for (row = 0, dstPtr = dstBuf; row < ntilesh;
         row++, dstPtr += (size_t)pitch * tileh * sampleSize) {
      for (col = 0, dstPtr2 = dstPtr; col < ntilesw;
           col++, tile++, dstPtr2 += ps * tilew * sampleSize) {
        int width = doTile ? min(tilew, w - col * tilew) : scaledw;
        int height = doTile ? min(tileh, h - row * tileh) : scaledh;

        if (doYUV) {
          double startDecode;

          if (tj3DecompressToYUV8(handle, jpegBufs[tile], jpegSizes[tile],
                                  yuvBuf, yuvAlign) == -1)
            THROW_TJ();
          startDecode = getTime();
          if (tj3DecodeYUV8(handle, yuvBuf, yuvAlign, dstPtr2, width, pitch,
                            height, pf) == -1)
            THROW_TJ();
          if (iter >= 0) elapsedDecode += getTime() - startDecode;
        } else {
          if (precision == 8) {
            if (tj3Decompress8(handle, jpegBufs[tile], jpegSizes[tile],
                               dstPtr2, pitch, pf) == -1)
              THROW_TJ();
          } else if (precision == 12) {
            if (tj3Decompress12(handle, jpegBufs[tile], jpegSizes[tile],
                                (short *)dstPtr2, pitch, pf) == -1)
              THROW_TJ();
          } else {
            if (tj3Decompress16(handle, jpegBufs[tile], jpegSizes[tile],
                                (unsigned short *)dstPtr2, pitch, pf) == -1)
              THROW_TJ();
          }
        }
      }
    }
    elapsed += getTime() - start;
    if (iter >= 0) {
      iter++;
      if (elapsed >= benchTime) break;
    } else if (elapsed >= warmup) {
      iter = 0;
      elapsed = elapsedDecode = 0.;
    }
  }
  if (doYUV) elapsed -= elapsedDecode;

  if (quiet) {
    printf("%-6s%s",
           sigfig((double)(w * h) / 1000000. * (double)iter / elapsed, 4,
                  tempStr, 1024),
           quiet == 2 ? "\n" : "  ");
    if (doYUV)
      printf("%s\n",
             sigfig((double)(w * h) / 1000000. * (double)iter / elapsedDecode,
                    4, tempStr, 1024));
    else if (quiet != 2) printf("\n");
  } else {
    printf("%s --> Frame rate:         %f fps\n",
           doYUV ? "Decomp to YUV" : "Decompress   ", (double)iter / elapsed);
    printf("                  Throughput:         %f Megapixels/sec\n",
           (double)(w * h) / 1000000. * (double)iter / elapsed);
    if (doYUV) {
      printf("YUV Decode    --> Frame rate:         %f fps\n",
             (double)iter / elapsedDecode);
      printf("                  Throughput:         %f Megapixels/sec\n",
             (double)(w * h) / 1000000. * (double)iter / elapsedDecode);
    }
  }

  if (!doWrite) goto bailout;

  if (sf.num != 1 || sf.denom != 1)
    SNPRINTF(sizeStr, 24, "%d_%d", sf.num, sf.denom);
  else if (tilew != w || tileh != h)
    SNPRINTF(sizeStr, 24, "%dx%d", tilew, tileh);
  else SNPRINTF(sizeStr, 24, "full");
  if (decompOnly)
    SNPRINTF(tempStr, 1024, "%s_%s.%s", fileName, sizeStr, ext);
  else
    SNPRINTF(tempStr, 1024, "%s_%s%s_%s.%s", fileName,
             lossless ? "LOSSLS" : subName[subsamp], qualStr, sizeStr, ext);

  if (precision == 8) {
    if (tj3SaveImage8(handle, tempStr, (unsigned char *)dstBuf, scaledw, 0,
                      scaledh, pf) == -1)
      THROW_TJ();
  } else if (precision == 12) {
    if (tj3SaveImage12(handle, tempStr, (short *)dstBuf, scaledw, 0, scaledh,
                       pf) == -1)
      THROW_TJ();
  } else {
    if (tj3SaveImage16(handle, tempStr, (unsigned short *)dstBuf, scaledw, 0,
                      scaledh, pf) == -1)
      THROW_TJ();
  }

bailout:
  if (file) fclose(file);
  tj3Destroy(handle);
  if (dstBufAlloc) free(dstBuf);
  free(yuvBuf);
  return retval;
}