static int fullTest()

in tjbench.c [375:621]


static int fullTest(tjhandle handle, void *srcBuf, int w, int h, int subsamp,
                    int jpegQual, char *fileName)
{
  char tempStr[1024], tempStr2[80];
  FILE *file = NULL;
  unsigned char **jpegBufs = NULL, *yuvBuf = NULL, *srcPtr, *srcPtr2;
  void *tmpBuf = NULL;
  double start, elapsed, elapsedEncode;
  int row, col, i, tilew = w, tileh = h, retval = 0;
  int iter;
  size_t totalJpegSize = 0, *jpegSizes = NULL, yuvSize = 0;
  int ps = tjPixelSize[pf];
  int ntilesw = 1, ntilesh = 1, pitch = w * ps;
  const char *pfStr = pixFormatStr[pf];

#if ULLONG_MAX > SIZE_MAX
  if ((unsigned long long)pitch * (unsigned long long)h *
      (unsigned long long)sampleSize > (unsigned long long)((size_t)-1))
    THROW("allocating temporary image buffer", "Image is too large");
#endif
  if ((tmpBuf = malloc((size_t)pitch * h * sampleSize)) == NULL)
    THROW_UNIX("allocating temporary image buffer");

  if (!quiet)
    printf(">>>>>  %s (%s) <--> %d-bit JPEG (%s %s%d)  <<<<<\n", pfStr,
           bottomUp ? "Bottom-up" : "Top-down", precision,
           lossless ? "Lossless" : subNameLong[subsamp],
           lossless ? "PSV" : "Q", jpegQual);

  for (tilew = doTile ? 8 : w, tileh = doTile ? 8 : h; ;
       tilew *= 2, tileh *= 2) {
    if (tilew > w) tilew = w;
    if (tileh > h) tileh = h;
    ntilesw = (w + tilew - 1) / tilew;
    ntilesh = (h + tileh - 1) / tileh;

    if ((jpegBufs = (unsigned char **)malloc(sizeof(unsigned char *) *
                                             ntilesw * ntilesh)) == NULL)
      THROW_UNIX("allocating JPEG tile array");
    memset(jpegBufs, 0, sizeof(unsigned char *) * ntilesw * ntilesh);
    if ((jpegSizes = (size_t *)malloc(sizeof(size_t) * ntilesw *
                                      ntilesh)) == NULL)
      THROW_UNIX("allocating JPEG size array");
    memset(jpegSizes, 0, sizeof(size_t) * ntilesw * ntilesh);

    if (noRealloc) {
      for (i = 0; i < ntilesw * ntilesh; i++) {
        size_t jpegBufSize = tj3JPEGBufSize(tilew, tileh, subsamp);

        if (jpegBufSize == 0)
          THROW_TJG();
        if ((jpegBufs[i] = tj3Alloc(jpegBufSize)) == NULL)
          THROW_UNIX("allocating JPEG tiles");
      }
    }

    /* Compression test */
    if (quiet == 1)
      printf("%-4s(%s)  %-2d/%-6s %-3d   ", pfStr, bottomUp ? "BU" : "TD",
             precision, lossless ? "LOSSLS" : subNameLong[subsamp], jpegQual);
    if (precision == 8) {
      for (i = 0; i < h; i++)
        memcpy(&((unsigned char *)tmpBuf)[pitch * i],
               &((unsigned char *)srcBuf)[w * ps * i], w * ps);
    } else {
      for (i = 0; i < h; i++)
        memcpy(&((unsigned short *)tmpBuf)[pitch * i],
               &((unsigned short *)srcBuf)[w * ps * i], w * ps * sampleSize);
    }

    if (tj3Set(handle, TJPARAM_NOREALLOC, noRealloc) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_SUBSAMP, subsamp) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_FASTDCT, fastDCT) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_OPTIMIZE, optimize) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_PROGRESSIVE, progressive) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_ARITHMETIC, arithmetic) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_LOSSLESS, lossless) == -1)
      THROW_TJ();
    if (lossless) {
      if (tj3Set(handle, TJPARAM_LOSSLESSPSV, jpegQual) == -1)
        THROW_TJ();
    } else {
      if (tj3Set(handle, TJPARAM_QUALITY, jpegQual) == -1)
        THROW_TJ();
    }
    if (tj3Set(handle, TJPARAM_RESTARTBLOCKS, restartIntervalBlocks) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_RESTARTROWS, restartIntervalRows) == -1)
      THROW_TJ();
    if (tj3Set(handle, TJPARAM_MAXMEMORY, maxMemory) == -1)
      THROW_TJ();

    if (doYUV) {
      yuvSize = tj3YUVBufSize(tilew, yuvAlign, tileh, 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 = elapsedEncode = 0.;
    while (1) {
      int tile = 0;

      totalJpegSize = 0;
      start = getTime();
      for (row = 0, srcPtr = srcBuf; row < ntilesh;
           row++, srcPtr += pitch * tileh * sampleSize) {
        for (col = 0, srcPtr2 = srcPtr; col < ntilesw;
             col++, tile++, srcPtr2 += ps * tilew * sampleSize) {
          int width = min(tilew, w - col * tilew);
          int height = min(tileh, h - row * tileh);

          if (doYUV) {
            double startEncode = getTime();

            if (tj3EncodeYUV8(handle, srcPtr2, width, pitch, height, pf,
                              yuvBuf, yuvAlign) == -1)
              THROW_TJ();
            if (iter >= 0) elapsedEncode += getTime() - startEncode;
            if (tj3CompressFromYUV8(handle, yuvBuf, width, yuvAlign, height,
                                    &jpegBufs[tile], &jpegSizes[tile]) == -1)
              THROW_TJ();
          } else {
            if (precision == 8) {
              if (tj3Compress8(handle, srcPtr2, width, pitch, height, pf,
                               &jpegBufs[tile], &jpegSizes[tile]) == -1)
                THROW_TJ();
            } else if (precision == 12) {
              if (tj3Compress12(handle, (short *)srcPtr2, width, pitch, height,
                                pf, &jpegBufs[tile], &jpegSizes[tile]) == -1)
                THROW_TJ();
            } else {
              if (tj3Compress16(handle, (unsigned short *)srcPtr2, width,
                                pitch, height, pf, &jpegBufs[tile],
                                &jpegSizes[tile]) == -1)
                THROW_TJ();
            }
          }
          totalJpegSize += jpegSizes[tile];
        }
      }
      elapsed += getTime() - start;
      if (iter >= 0) {
        iter++;
        if (elapsed >= benchTime) break;
      } else if (elapsed >= warmup) {
        iter = 0;
        elapsed = elapsedEncode = 0.;
      }
    }
    if (doYUV) elapsed -= elapsedEncode;

    if (quiet == 1) printf("%-5d  %-5d   ", tilew, tileh);
    if (quiet) {
      if (doYUV)
        printf("%-6s%s",
               sigfig((double)(w * h) / 1000000. *
                      (double)iter / elapsedEncode, 4, tempStr, 1024),
               quiet == 2 ? "\n" : "  ");
      printf("%-6s%s",
             sigfig((double)(w * h) / 1000000. * (double)iter / elapsed, 4,
                    tempStr, 1024),
             quiet == 2 ? "\n" : "  ");
      printf("%-6s%s",
             sigfig((double)(w * h * ps) / (double)totalJpegSize, 4, tempStr2,
                    80),
             quiet == 2 ? "\n" : "  ");
    } else {
      printf("\n%s size: %d x %d\n", doTile ? "Tile" : "Image", tilew, tileh);
      if (doYUV) {
        printf("Encode YUV    --> Frame rate:         %f fps\n",
               (double)iter / elapsedEncode);
        printf("                  Output image size:  %lu bytes\n",
               (unsigned long)yuvSize);
        printf("                  Compression ratio:  %f:1\n",
               (double)(w * h * ps) / (double)yuvSize);
        printf("                  Throughput:         %f Megapixels/sec\n",
               (double)(w * h) / 1000000. * (double)iter / elapsedEncode);
        printf("                  Output bit stream:  %f Megabits/sec\n",
               (double)yuvSize * 8. / 1000000. * (double)iter / elapsedEncode);
      }
      printf("%s --> Frame rate:         %f fps\n",
             doYUV ? "Comp from YUV" : "Compress     ",
             (double)iter / elapsed);
      printf("                  Output image size:  %lu bytes\n",
             (unsigned long)totalJpegSize);
      printf("                  Compression ratio:  %f:1\n",
             (double)(w * h * ps) / (double)totalJpegSize);
      printf("                  Throughput:         %f Megapixels/sec\n",
             (double)(w * h) / 1000000. * (double)iter / elapsed);
      printf("                  Output bit stream:  %f Megabits/sec\n",
             (double)totalJpegSize * 8. / 1000000. * (double)iter / elapsed);
    }
    if (tilew == w && tileh == h && doWrite) {
     SNPRINTF(tempStr, 1024, "%s_%s_%s%d.jpg", fileName,
              lossless ? "LOSSLS" : subName[subsamp],
              lossless ? "PSV" : "Q", jpegQual);
      if ((file = fopen(tempStr, "wb")) == NULL)
        THROW_UNIX("opening reference image");
      if (fwrite(jpegBufs[0], jpegSizes[0], 1, file) != 1)
        THROW_UNIX("writing reference image");
      fclose(file);  file = NULL;
      if (!quiet) printf("Reference image written to %s\n", tempStr);
    }

    /* Decompression test */
    if (!compOnly) {
      if (decomp(jpegBufs, jpegSizes, tmpBuf, w, h, subsamp, jpegQual,
                 fileName, tilew, tileh) == -1)
        goto bailout;
    } else if (quiet == 1) printf("N/A\n");

    for (i = 0; i < ntilesw * ntilesh; i++) {
      tj3Free(jpegBufs[i]);
      jpegBufs[i] = NULL;
    }
    free(jpegBufs);  jpegBufs = NULL;
    free(jpegSizes);  jpegSizes = NULL;
    if (doYUV) {
      free(yuvBuf);  yuvBuf = NULL;
    }

    if (tilew == w && tileh == h) break;
  }

bailout:
  if (file) fclose(file);
  if (jpegBufs) {
    for (i = 0; i < ntilesw * ntilesh; i++)
      tj3Free(jpegBufs[i]);
  }
  free(jpegBufs);
  free(yuvBuf);
  free(jpegSizes);
  free(tmpBuf);
  return retval;
}