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;
}