bool WriteJpeg( const char * destinationFile, const unsigned char * rgbxBuffer, int width, int height ) { tjhandle tj = tjInitCompress(); unsigned char * jpegBuf = NULL; unsigned long jpegSize = 0; const int r = tjCompress2( tj, ( unsigned char * )rgbxBuffer, // TJ isn't const correct... width, width * 4, height, TJPF_RGBX, &jpegBuf, &jpegSize, TJSAMP_444 /* TJSAMP_422 */, 90 /* jpegQual */, 0 /* flags */ ); if ( r != 0 ) { LOG_TJ( "tjCompress2 returned %s for %s", tjGetErrorStr(), destinationFile ); return false; } FILE * f = fopen( destinationFile, "wb" ); if ( f != NULL ) { fwrite( jpegBuf, jpegSize, 1, f ); fclose( f ); } else { LOG_TJ( "WriteJpeg failed to write to %s", destinationFile ); return false; } tjFree( jpegBuf ); tjDestroy( tj ); return true; }
void WriteJpeg( const char * fullName, const unsigned char * rgbxBuffer, int width, int height ) { tjhandle tj = tjInitCompress(); unsigned char * jpegBuf = NULL; unsigned long jpegSize = 0; const int r = tjCompress2( tj, ( unsigned char * )rgbxBuffer, // TJ isn't const correct... width, width * 4, height, TJPF_RGBX, &jpegBuf, &jpegSize, TJSAMP_444 /* TJSAMP_422 */, 90 /* jpegQual */, 0 /* flags */ ); if ( r != 0 ) { LOG( "tjCompress2 returned %s for %s", tjGetErrorStr(), fullName ); return; } MemBuffer toFile( jpegBuf, jpegSize ); toFile.WriteToFile( fullName ); tjFree( jpegBuf ); tjDestroy( tj ); }
QByteArray ImageJpegCompressor::computeJpeg(const ImageWrapper& sourceImage, const QRect& imageRegion) { // tjCompress API is incorrect and takes a non-const input buffer, even // though it does not modify it. It can "safely" be cast to non-const // pointer to comply to the incorrect API. unsigned char* tjSrcBuffer = (unsigned char*)sourceImage.data; tjSrcBuffer += imageRegion.y() * sourceImage.width * sourceImage.getBytesPerPixel(); tjSrcBuffer += imageRegion.x() * sourceImage.getBytesPerPixel(); const int tjWidth = imageRegion.width(); // assume imageBuffer isn't padded const int tjPitch = sourceImage.width * sourceImage.getBytesPerPixel(); const int tjHeight = imageRegion.height(); const int tjPixelFormat = getTurboJpegFormat(sourceImage.pixelFormat); unsigned char* tjJpegBuf = 0; unsigned long tjJpegSize = 0; const int tjJpegSubsamp = TJSAMP_444; const int tjJpegQual = sourceImage.compressionQuality; const int tjFlags = 0; // or: TJFLAG_BOTTOMUP int err = tjCompress2(_tjHandle, tjSrcBuffer, tjWidth, tjPitch, tjHeight, tjPixelFormat, &tjJpegBuf, &tjJpegSize, tjJpegSubsamp, tjJpegQual, tjFlags); if (err != 0) { std::cerr << "libjpeg-turbo image conversion failure" << std::endl; return QByteArray(); } // move the JPEG buffer to a byte array const QByteArray jpegData((char*)tjJpegBuf, tjJpegSize); // free the libjpeg-turbo allocated memory tjFree(tjJpegBuf); return jpegData; }
int decompTest(char *filename) { FILE *file=NULL; tjhandle handle=NULL; unsigned char **jpegbuf=NULL, *srcbuf=NULL; unsigned long *jpegsize=NULL, srcsize, totaljpegsize; tjtransform *t=NULL; int w=0, h=0, subsamp=-1, cs=-1, _w, _h, _tilew, _tileh, _ntilesw, _ntilesh, _subsamp; char *temp=NULL, tempstr[80], tempstr2[80]; int row, col, i, iter, tilew, tileh, ntilesw=1, ntilesh=1, retval=0; double start, elapsed; int ps=tjPixelSize[pf], tile; if((file=fopen(filename, "rb"))==NULL) _throwunix("opening file"); if(fseek(file, 0, SEEK_END)<0 || (srcsize=ftell(file))==(unsigned long)-1) _throwunix("determining file size"); if((srcbuf=(unsigned char *)malloc(srcsize))==NULL) _throwunix("allocating memory"); if(fseek(file, 0, SEEK_SET)<0) _throwunix("setting file position"); if(fread(srcbuf, srcsize, 1, file)<1) _throwunix("reading JPEG data"); fclose(file); file=NULL; temp=strrchr(filename, '.'); if(temp!=NULL) *temp='\0'; if((handle=tjInitTransform())==NULL) _throwtj("executing tjInitTransform()"); if(tjDecompressHeader3(handle, srcbuf, srcsize, &w, &h, &subsamp, &cs)==-1) _throwtj("executing tjDecompressHeader3()"); if(cs==TJCS_YCCK || cs==TJCS_CMYK) { pf=TJPF_CMYK; ps=tjPixelSize[pf]; } if(quiet==1) { printf("All performance values in Mpixels/sec\n\n"); printf("Bitmap JPEG JPEG %s %s Xform Comp Decomp ", dotile? "Tile ":"Image", dotile? "Tile ":"Image"); if(doyuv) printf("Decode"); printf("\n"); printf("Format CS Subsamp Width Height Perf Ratio Perf "); if(doyuv) printf("Perf"); printf("\n\n"); } else if(!quiet) printf(">>>>> JPEG %s --> %s (%s) <<<<<\n", formatName(subsamp, cs, tempstr), pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "Bottom-up":"Top-down"); for(tilew=dotile? 16:w, tileh=dotile? 16: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((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *) *ntilesw*ntilesh))==NULL) _throwunix("allocating JPEG tile array"); memset(jpegbuf, 0, sizeof(unsigned char *)*ntilesw*ntilesh); if((jpegsize=(unsigned long *)malloc(sizeof(unsigned long) *ntilesw*ntilesh))==NULL) _throwunix("allocating JPEG size array"); memset(jpegsize, 0, sizeof(unsigned long)*ntilesw*ntilesh); if((flags&TJFLAG_NOREALLOC)!=0 || !dotile) for(i=0; i<ntilesw*ntilesh; i++) { if((jpegbuf[i]=(unsigned char *)tjAlloc(tjBufSize(tilew, tileh, subsamp)))==NULL) _throwunix("allocating JPEG tiles"); } _w=w; _h=h; _tilew=tilew; _tileh=tileh; if(!quiet) { printf("\n%s size: %d x %d", dotile? "Tile":"Image", _tilew, _tileh); if(sf.num!=1 || sf.denom!=1) printf(" --> %d x %d", TJSCALED(_w, sf), TJSCALED(_h, sf)); printf("\n"); } else if(quiet==1) { printf("%-4s (%s) %-5s %-5s ", pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "BU":"TD", csName[cs], subNameLong[subsamp]); printf("%-5d %-5d ", tilew, tileh); } _subsamp=subsamp; if(dotile || xformop!=TJXOP_NONE || xformopt!=0 || customFilter) { if((t=(tjtransform *)malloc(sizeof(tjtransform)*ntilesw*ntilesh)) ==NULL) _throwunix("allocating image transform array"); if(xformop==TJXOP_TRANSPOSE || xformop==TJXOP_TRANSVERSE || xformop==TJXOP_ROT90 || xformop==TJXOP_ROT270) { _w=h; _h=w; _tilew=tileh; _tileh=tilew; } if(xformopt&TJXOPT_GRAY) _subsamp=TJ_GRAYSCALE; if(xformop==TJXOP_HFLIP || xformop==TJXOP_ROT180) _w=_w-(_w%tjMCUWidth[_subsamp]); if(xformop==TJXOP_VFLIP || xformop==TJXOP_ROT180) _h=_h-(_h%tjMCUHeight[_subsamp]); if(xformop==TJXOP_TRANSVERSE || xformop==TJXOP_ROT90) _w=_w-(_w%tjMCUHeight[_subsamp]); if(xformop==TJXOP_TRANSVERSE || xformop==TJXOP_ROT270) _h=_h-(_h%tjMCUWidth[_subsamp]); _ntilesw=(_w+_tilew-1)/_tilew; _ntilesh=(_h+_tileh-1)/_tileh; if(xformop==TJXOP_TRANSPOSE || xformop==TJXOP_TRANSVERSE || xformop==TJXOP_ROT90 || xformop==TJXOP_ROT270) { if(_subsamp==TJSAMP_422) _subsamp=TJSAMP_440; else if(_subsamp==TJSAMP_440) _subsamp=TJSAMP_422; } for(row=0, tile=0; row<_ntilesh; row++) { for(col=0; col<_ntilesw; col++, tile++) { t[tile].r.w=min(_tilew, _w-col*_tilew); t[tile].r.h=min(_tileh, _h-row*_tileh); t[tile].r.x=col*_tilew; t[tile].r.y=row*_tileh; t[tile].op=xformop; t[tile].options=xformopt|TJXOPT_TRIM; t[tile].customFilter=customFilter; if(t[tile].options&TJXOPT_NOOUTPUT && jpegbuf[tile]) { tjFree(jpegbuf[tile]); jpegbuf[tile]=NULL; } } } iter=-warmup; elapsed=0.; while(1) { start=gettime(); if(tjTransform(handle, srcbuf, srcsize, _ntilesw*_ntilesh, jpegbuf, jpegsize, t, flags)==-1) _throwtj("executing tjTransform()"); iter++; if(iter>=1) { elapsed+=gettime()-start; if(elapsed>=benchtime) break; } } free(t); t=NULL; for(tile=0, totaljpegsize=0; tile<_ntilesw*_ntilesh; tile++) totaljpegsize+=jpegsize[tile]; if(quiet) { printf("%-6s%s%-6s%s", sigfig((double)(w*h)/1000000./elapsed, 4, tempstr, 80), quiet==2? "\n":" ", sigfig((double)(w*h*ps)/(double)totaljpegsize, 4, tempstr2, 80), quiet==2? "\n":" "); } else if(!quiet) { printf("Transform --> Frame rate: %f fps\n", 1.0/elapsed); printf(" Output image size: %lu bytes\n", totaljpegsize); printf(" Compression ratio: %f:1\n", (double)(w*h*ps)/(double)totaljpegsize); printf(" Throughput: %f Megapixels/sec\n", (double)(w*h)/1000000./elapsed); printf(" Output bit stream: %f Megabits/sec\n", (double)totaljpegsize*8./1000000./elapsed); } } else { if(quiet==1) printf("N/A N/A "); jpegsize[0]=srcsize; memcpy(jpegbuf[0], srcbuf, srcsize); } if(w==tilew) _tilew=_w; if(h==tileh) _tileh=_h; if(!(xformopt&TJXOPT_NOOUTPUT)) { if(decomp(NULL, jpegbuf, jpegsize, NULL, _w, _h, _subsamp, 0, filename, _tilew, _tileh)==-1) goto bailout; } else if(quiet==1) printf("N/A\n"); for(i=0; i<ntilesw*ntilesh; i++) { tjFree(jpegbuf[i]); jpegbuf[i]=NULL; } free(jpegbuf); jpegbuf=NULL; if(jpegsize) {free(jpegsize); jpegsize=NULL;} if(tilew==w && tileh==h) break; } bailout: if(file) {fclose(file); file=NULL;} if(jpegbuf) { for(i=0; i<ntilesw*ntilesh; i++) { if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; } free(jpegbuf); jpegbuf=NULL; } if(jpegsize) {free(jpegsize); jpegsize=NULL;} if(srcbuf) {free(srcbuf); srcbuf=NULL;} if(t) {free(t); t=NULL;} if(handle) {tjDestroy(handle); handle=NULL;} return retval; }
int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual, char *filename) { char tempstr[1024], tempstr2[80]; FILE *file=NULL; tjhandle handle=NULL; unsigned char **jpegbuf=NULL, *yuvbuf=NULL, *tmpbuf=NULL, *srcptr, *srcptr2; double start, elapsed, elapsedEncode; int totaljpegsize=0, row, col, i, tilew=w, tileh=h, retval=0; int iter, yuvsize=0; unsigned long *jpegsize=NULL; int ps=tjPixelSize[pf]; int ntilesw=1, ntilesh=1, pitch=w*ps; const char *pfStr=pixFormatStr[pf]; if((tmpbuf=(unsigned char *)malloc(pitch*h)) == NULL) _throwunix("allocating temporary image buffer"); if(!quiet) printf(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pfStr, (flags&TJFLAG_BOTTOMUP)? "Bottom-up":"Top-down", subNameLong[subsamp], 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((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *) *ntilesw*ntilesh))==NULL) _throwunix("allocating JPEG tile array"); memset(jpegbuf, 0, sizeof(unsigned char *)*ntilesw*ntilesh); if((jpegsize=(unsigned long *)malloc(sizeof(unsigned long) *ntilesw*ntilesh))==NULL) _throwunix("allocating JPEG size array"); memset(jpegsize, 0, sizeof(unsigned long)*ntilesw*ntilesh); if((flags&TJFLAG_NOREALLOC)!=0) for(i=0; i<ntilesw*ntilesh; i++) { if((jpegbuf[i]=(unsigned char *)tjAlloc(tjBufSize(tilew, tileh, subsamp)))==NULL) _throwunix("allocating JPEG tiles"); } /* Compression test */ if(quiet==1) printf("%-4s (%s) %-5s %-3d ", pfStr, (flags&TJFLAG_BOTTOMUP)? "BU":"TD", subNameLong[subsamp], jpegqual); for(i=0; i<h; i++) memcpy(&tmpbuf[pitch*i], &srcbuf[w*ps*i], w*ps); if((handle=tjInitCompress())==NULL) _throwtj("executing tjInitCompress()"); if(doyuv) { yuvsize=tjBufSizeYUV2(tilew, yuvpad, tileh, subsamp); if((yuvbuf=(unsigned char *)malloc(yuvsize))==NULL) _throwunix("allocating YUV buffer"); memset(yuvbuf, 127, yuvsize); } /* Benchmark */ iter=-warmup; elapsed=elapsedEncode=0.; while(1) { int tile=0; totaljpegsize=0; start=gettime(); for(row=0, srcptr=srcbuf; row<ntilesh; row++, srcptr+=pitch*tileh) { for(col=0, srcptr2=srcptr; col<ntilesw; col++, tile++, srcptr2+=ps*tilew) { int width=min(tilew, w-col*tilew); int height=min(tileh, h-row*tileh); if(doyuv) { double startEncode=gettime(); if(tjEncodeYUV3(handle, srcptr2, width, pitch, height, pf, yuvbuf, yuvpad, subsamp, flags)==-1) _throwtj("executing tjEncodeYUV3()"); if(iter>=0) elapsedEncode+=gettime()-startEncode; if(tjCompressFromYUV(handle, yuvbuf, width, yuvpad, height, subsamp, &jpegbuf[tile], &jpegsize[tile], jpegqual, flags)==-1) _throwtj("executing tjCompressFromYUV()"); } else { if(tjCompress2(handle, srcptr2, width, pitch, height, pf, &jpegbuf[tile], &jpegsize[tile], subsamp, jpegqual, flags)==-1) _throwtj("executing tjCompress2()"); } totaljpegsize+=jpegsize[tile]; } } iter++; if(iter>=1) { elapsed+=gettime()-start; if(elapsed>=benchtime) break; } } if(doyuv) elapsed-=elapsedEncode; if(tjDestroy(handle)==-1) _throwtj("executing tjDestroy()"); handle=NULL; 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: %d bytes\n", 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: %d bytes\n", 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) { snprintf(tempstr, 1024, "%s_%s_Q%d.jpg", filename, subName[subsamp], jpegqual); if((file=fopen(tempstr, "wb"))==NULL) _throwunix("opening reference image"); if(fwrite(jpegbuf[0], jpegsize[0], 1, file)!=1) _throwunix("writing reference image"); fclose(file); file=NULL; if(!quiet) printf("Reference image written to %s\n", tempstr); } /* Decompression test */ if(!componly) { if(decomp(srcbuf, jpegbuf, jpegsize, tmpbuf, w, h, subsamp, jpegqual, filename, tilew, tileh)==-1) goto bailout; } for(i=0; i<ntilesw*ntilesh; i++) { if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; } free(jpegbuf); jpegbuf=NULL; free(jpegsize); jpegsize=NULL; if(doyuv) { free(yuvbuf); yuvbuf=NULL; } if(tilew==w && tileh==h) break; } bailout: if(file) {fclose(file); file=NULL;} if(jpegbuf) { for(i=0; i<ntilesw*ntilesh; i++) { if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; } free(jpegbuf); jpegbuf=NULL; } if(yuvbuf) {free(yuvbuf); yuvbuf=NULL;} if(jpegsize) {free(jpegsize); jpegsize=NULL;} if(tmpbuf) {free(tmpbuf); tmpbuf=NULL;} if(handle) {tjDestroy(handle); handle=NULL;} return retval; }
int main(int argc, char *argv[]) { unsigned char *srcBuf = NULL; int w = 0, h = 0, i, j, minQual = -1, maxQual = -1; char *temp; int minArg = 2, retval = 0, subsamp = -1; if ((scalingFactors = tjGetScalingFactors(&nsf)) == NULL || nsf == 0) _throw("executing tjGetScalingFactors()", tjGetErrorStr()); if (argc < minArg) usage(argv[0]); temp = strrchr(argv[1], '.'); if (temp != NULL) { if (!strcasecmp(temp, ".bmp")) ext = "bmp"; if (!strcasecmp(temp, ".jpg") || !strcasecmp(temp, ".jpeg")) decompOnly = 1; } printf("\n"); if (!decompOnly) { minArg = 3; if (argc < minArg) usage(argv[0]); if ((minQual = atoi(argv[2])) < 1 || minQual > 100) { puts("ERROR: Quality must be between 1 and 100."); exit(1); } if ((temp = strchr(argv[2], '-')) != NULL && strlen(temp) > 1 && sscanf(&temp[1], "%d", &maxQual) == 1 && maxQual > minQual && maxQual >= 1 && maxQual <= 100) {} else maxQual = minQual; } if (argc > minArg) { for (i = minArg; i < argc; i++) { if (!strcasecmp(argv[i], "-tile")) { doTile = 1; xformOpt |= TJXOPT_CROP; } else if (!strcasecmp(argv[i], "-fastupsample")) { printf("Using fast upsampling code\n\n"); flags |= TJFLAG_FASTUPSAMPLE; } else if (!strcasecmp(argv[i], "-fastdct")) { printf("Using fastest DCT/IDCT algorithm\n\n"); flags |= TJFLAG_FASTDCT; } else if (!strcasecmp(argv[i], "-accuratedct")) { printf("Using most accurate DCT/IDCT algorithm\n\n"); flags |= TJFLAG_ACCURATEDCT; } else if (!strcasecmp(argv[i], "-progressive")) { printf("Using progressive entropy coding\n\n"); flags |= TJFLAG_PROGRESSIVE; } else if (!strcasecmp(argv[i], "-rgb")) pf = TJPF_RGB; else if (!strcasecmp(argv[i], "-rgbx")) pf = TJPF_RGBX; else if (!strcasecmp(argv[i], "-bgr")) pf = TJPF_BGR; else if (!strcasecmp(argv[i], "-bgrx")) pf = TJPF_BGRX; else if (!strcasecmp(argv[i], "-xbgr")) pf = TJPF_XBGR; else if (!strcasecmp(argv[i], "-xrgb")) pf = TJPF_XRGB; else if (!strcasecmp(argv[i], "-cmyk")) pf = TJPF_CMYK; else if (!strcasecmp(argv[i], "-bottomup")) flags |= TJFLAG_BOTTOMUP; else if (!strcasecmp(argv[i], "-quiet")) quiet = 1; else if (!strcasecmp(argv[i], "-qq")) quiet = 2; else if (!strcasecmp(argv[i], "-scale") && i < argc - 1) { int temp1 = 0, temp2 = 0, match = 0; if (sscanf(argv[++i], "%d/%d", &temp1, &temp2) == 2) { for (j = 0; j < nsf; j++) { if ((double)temp1 / (double)temp2 == (double)scalingFactors[j].num / (double)scalingFactors[j].denom) { sf = scalingFactors[j]; match = 1; break; } } if (!match) usage(argv[0]); } else usage(argv[0]); } else if (!strcasecmp(argv[i], "-hflip")) xformOp = TJXOP_HFLIP; else if (!strcasecmp(argv[i], "-vflip")) xformOp = TJXOP_VFLIP; else if (!strcasecmp(argv[i], "-transpose")) xformOp = TJXOP_TRANSPOSE; else if (!strcasecmp(argv[i], "-transverse")) xformOp = TJXOP_TRANSVERSE; else if (!strcasecmp(argv[i], "-rot90")) xformOp = TJXOP_ROT90; else if (!strcasecmp(argv[i], "-rot180")) xformOp = TJXOP_ROT180; else if (!strcasecmp(argv[i], "-rot270")) xformOp = TJXOP_ROT270; else if (!strcasecmp(argv[i], "-grayscale")) xformOpt |= TJXOPT_GRAY; else if (!strcasecmp(argv[i], "-custom")) customFilter = dummyDCTFilter; else if (!strcasecmp(argv[i], "-nooutput")) xformOpt |= TJXOPT_NOOUTPUT; else if (!strcasecmp(argv[i], "-copynone")) xformOpt |= TJXOPT_COPYNONE; else if (!strcasecmp(argv[i], "-benchtime") && i < argc - 1) { double temp = atof(argv[++i]); if (temp > 0.0) benchTime = temp; else usage(argv[0]); } else if (!strcasecmp(argv[i], "-warmup") && i < argc - 1) { double temp = atof(argv[++i]); if (temp >= 0.0) warmup = temp; else usage(argv[0]); printf("Warmup time = %.1f seconds\n\n", warmup); } else if (!strcasecmp(argv[i], "-alloc")) flags &= (~TJFLAG_NOREALLOC); else if (!strcasecmp(argv[i], "-bmp")) ext = "bmp"; else if (!strcasecmp(argv[i], "-yuv")) { printf("Testing YUV planar encoding/decoding\n\n"); doYUV = 1; } else if (!strcasecmp(argv[i], "-yuvpad") && i < argc - 1) { int temp = atoi(argv[++i]); if (temp >= 1) yuvPad = temp; } else if (!strcasecmp(argv[i], "-subsamp") && i < argc - 1) { i++; if (toupper(argv[i][0]) == 'G') subsamp = TJSAMP_GRAY; else { int temp = atoi(argv[i]); switch (temp) { case 444: subsamp = TJSAMP_444; break; case 422: subsamp = TJSAMP_422; break; case 440: subsamp = TJSAMP_440; break; case 420: subsamp = TJSAMP_420; break; case 411: subsamp = TJSAMP_411; break; } } } else if (!strcasecmp(argv[i], "-componly")) compOnly = 1; else if (!strcasecmp(argv[i], "-nowrite")) doWrite = 0; else if (!strcasecmp(argv[i], "-stoponwarning")) flags |= TJFLAG_STOPONWARNING; else usage(argv[0]); } } if ((sf.num != 1 || sf.denom != 1) && doTile) { printf("Disabling tiled compression/decompression tests, because those tests do not\n"); printf("work when scaled decompression is enabled.\n"); doTile = 0; } if ((flags & TJFLAG_NOREALLOC) == 0 && doTile) { printf("Disabling tiled compression/decompression tests, because those tests do not\n"); printf("work when dynamic JPEG buffer allocation is enabled.\n\n"); doTile = 0; } if (!decompOnly) { if ((srcBuf = tjLoadImage(argv[1], &w, 1, &h, &pf, flags)) == NULL) _throwtjg("loading bitmap"); temp = strrchr(argv[1], '.'); if (temp != NULL) *temp = '\0'; } if (quiet == 1 && !decompOnly) { printf("All performance values in Mpixels/sec\n\n"); printf("Bitmap JPEG JPEG %s %s ", doTile ? "Tile " : "Image", doTile ? "Tile " : "Image"); if (doYUV) printf("Encode "); printf("Comp Comp Decomp "); if (doYUV) printf("Decode"); printf("\n"); printf("Format Subsamp Qual Width Height "); if (doYUV) printf("Perf "); printf("Perf Ratio Perf "); if (doYUV) printf("Perf"); printf("\n\n"); } if (decompOnly) { decompTest(argv[1]); printf("\n"); goto bailout; } if (subsamp >= 0 && subsamp < TJ_NUMSAMP) { for (i = maxQual; i >= minQual; i--) fullTest(srcBuf, w, h, subsamp, i, argv[1]); printf("\n"); } else { if (pf != TJPF_CMYK) { for (i = maxQual; i >= minQual; i--) fullTest(srcBuf, w, h, TJSAMP_GRAY, i, argv[1]); printf("\n"); } for (i = maxQual; i >= minQual; i--) fullTest(srcBuf, w, h, TJSAMP_420, i, argv[1]); printf("\n"); for (i = maxQual; i >= minQual; i--) fullTest(srcBuf, w, h, TJSAMP_422, i, argv[1]); printf("\n"); for (i = maxQual; i >= minQual; i--) fullTest(srcBuf, w, h, TJSAMP_444, i, argv[1]); printf("\n"); } bailout: if (srcBuf) tjFree(srcBuf); return retval; }