JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors (JNIEnv *env, jclass cls) { jclass sfcls=NULL; jfieldID fid=0; tjscalingfactor *sf=NULL; int n=0, i; jobject sfobj=NULL; jobjectArray sfjava=NULL; if((sf=tjGetScalingFactors(&n))==NULL || n==0) _throw(tjGetErrorStr()); bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor")); bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0)); for(i=0; i<n; i++) { bailif0(sfobj=(*env)->AllocObject(env, sfcls)); bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I")); (*env)->SetIntField(env, sfobj, fid, sf[i].num); bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I")); (*env)->SetIntField(env, sfobj, fid, sf[i].denom); (*env)->SetObjectArrayElement(env, sfjava, i, sfobj); } bailout: return sfjava; }
void BEJPEG::adjust_dimensions ( const int image_width, const int image_height ) { int number_of_scaling_factors = 0; tjscalingfactor * scaling_factor = tjGetScalingFactors ( &number_of_scaling_factors ); if ( width < 1 && height < 1 ) { width = image_width; height = image_height; } else if ( width > 0 && height < 1 ) { height = ceil ( ((double)width / (double)image_width) * image_height ); } else if ( width < 1 && height > 0 ) { width = ceil ( ((double)height / (double)image_width) * image_height ); } if ( scale != 0.0 ) { width = ceil ( (double)width * scale ); height = ceil ( (double)height * scale ); } for ( int i = 0; i < number_of_scaling_factors ; i++ ) { const int scaled_width = TJSCALED ( image_width, scaling_factor[i] ); const int scaled_height = TJSCALED ( image_height, scaling_factor[i] ); if ( scaled_width <= width && scaled_height <= height ) { width = scaled_width; height = scaled_height; break; } } } // adjust_dimensions
/* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth, jintArray jDstStrides, jint desiredHeight, jint flags) { tjhandle handle=0; jbyteArray jDstPlanes[3]={NULL, NULL, NULL}; unsigned char *jpegBuf=NULL, *dstPlanes[3]; int *dstOffsets=NULL, *dstStrides=NULL; int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0; int nc=0, i, width, height, scaledWidth, scaledHeight, nsf=0; tjscalingfactor *sf; gethandle(); if((*env)->GetArrayLength(env, src)<jpegSize) _throwarg("Source buffer is not large enough"); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth=(int)(*env)->GetIntField(env, obj, _fid); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight=(int)(*env)->GetIntField(env, obj, _fid); nc=(jpegSubsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3); width=desiredWidth; height=desiredHeight; if(width==0) width=jpegWidth; if(height==0) height=jpegHeight; sf=tjGetScalingFactors(&nsf); if(!sf || nsf<1) _throwarg(tjGetErrorStr()); for(i=0; i<nsf; i++) { scaledWidth=TJSCALED(jpegWidth, sf[i]); scaledHeight=TJSCALED(jpegHeight, sf[i]); if(scaledWidth<=width && scaledHeight<=height) break; } bailif0(dstOffsets=(*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); bailif0(dstStrides=(*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); for(i=0; i<nc; i++) { int planeSize=tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight, jpegSubsamp); int pw=tjPlaneWidth(i, scaledWidth, jpegSubsamp); if(planeSize<0 || pw<0) _throwarg(tjGetErrorStr()); if(dstOffsets[i]<0) _throwarg("Invalid argument in decompressToYUV()"); if(dstStrides[i]<0 && dstOffsets[i]-planeSize+pw<0) _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); bailif0(jDstPlanes[i]=(*env)->GetObjectArrayElement(env, dstobjs, i)); if((*env)->GetArrayLength(env, jDstPlanes[i])<dstOffsets[i]+planeSize) _throwarg("Destination plane is not large enough"); bailif0(dstPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); dstPlanes[i]=&dstPlanes[i][dstOffsets[i]]; } bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); if(tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize, dstPlanes, desiredWidth, dstStrides, desiredHeight, flags)==-1) _throwtj(); bailout: if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); for(i=0; i<nc; i++) { if(dstPlanes[i] && jDstPlanes[i]) (*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i], 0); } if(dstStrides) (*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0); if(dstOffsets) (*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0); return; }
int main(int argc, char *argv[]) { unsigned char *srcbuf=NULL; int w, h, i, j; int minqual=-1, maxqual=-1; char *temp; int minarg=2; int retval=0; if((scalingfactors=tjGetScalingFactors(&nsf))==NULL || nsf==0) _throwtj("executing tjGetScalingFactors()"); 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(argc>minarg) { for(i=minarg; i<argc; i++) { if(!strcasecmp(argv[i], "-yuvencode")) { printf("Testing YUV planar encoding\n\n"); yuv=YUVENCODE; maxqual=minqual=100; } if(!strcasecmp(argv[i], "-yuvdecode")) { printf("Testing YUV planar decoding\n\n"); yuv=YUVDECODE; } } } if(!decomponly && yuv!=YUVENCODE) { 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; } if(!strcasecmp(argv[i], "-forcesse3")) { printf("Forcing SSE3 code\n\n"); flags|=TJFLAG_FORCESSE3; } if(!strcasecmp(argv[i], "-forcesse2")) { printf("Forcing SSE2 code\n\n"); flags|=TJFLAG_FORCESSE2; } if(!strcasecmp(argv[i], "-forcesse")) { printf("Forcing SSE code\n\n"); flags|=TJFLAG_FORCESSE; } if(!strcasecmp(argv[i], "-forcemmx")) { printf("Forcing MMX code\n\n"); flags|=TJFLAG_FORCEMMX; } if(!strcasecmp(argv[i], "-fastupsample")) { printf("Using fast upsampling code\n\n"); flags|=TJFLAG_FASTUPSAMPLE; } if(!strcasecmp(argv[i], "-rgb")) pf=TJPF_RGB; if(!strcasecmp(argv[i], "-rgbx")) pf=TJPF_RGBX; if(!strcasecmp(argv[i], "-bgr")) pf=TJPF_BGR; if(!strcasecmp(argv[i], "-bgrx")) pf=TJPF_BGRX; if(!strcasecmp(argv[i], "-xbgr")) pf=TJPF_XBGR; if(!strcasecmp(argv[i], "-xrgb")) pf=TJPF_XRGB; if(!strcasecmp(argv[i], "-bottomup")) flags|=TJFLAG_BOTTOMUP; if(!strcasecmp(argv[i], "-quiet")) quiet=1; if(!strcasecmp(argv[i], "-qq")) quiet=2; 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(temp1==scalingfactors[j].num && temp2==scalingfactors[j].denom) { sf=scalingfactors[j]; match=1; break; } } if(!match) usage(argv[0]); } else usage(argv[0]); } if(!strcasecmp(argv[i], "-hflip")) xformop=TJXOP_HFLIP; if(!strcasecmp(argv[i], "-vflip")) xformop=TJXOP_VFLIP; if(!strcasecmp(argv[i], "-transpose")) xformop=TJXOP_TRANSPOSE; if(!strcasecmp(argv[i], "-transverse")) xformop=TJXOP_TRANSVERSE; if(!strcasecmp(argv[i], "-rot90")) xformop=TJXOP_ROT90; if(!strcasecmp(argv[i], "-rot180")) xformop=TJXOP_ROT180; if(!strcasecmp(argv[i], "-rot270")) xformop=TJXOP_ROT270; if(!strcasecmp(argv[i], "-grayscale")) xformopt|=TJXOPT_GRAY; if(!strcasecmp(argv[i], "-benchtime") && i<argc-1) { double temp=atof(argv[++i]); if(temp>0.0) benchtime=temp; else usage(argv[0]); } if(!strcmp(argv[i], "-?")) usage(argv[0]); if(!strcasecmp(argv[i], "-alloc")) flags&=(~TJFLAG_NOREALLOC); if(!strcasecmp(argv[i], "-bmp")) ext="bmp"; } } 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(yuv && dotile) { printf("Disabling tiled compression/decompression tests, because those tests do not\n"); printf("work when YUV encoding or decoding is enabled.\n\n"); dotile=0; } if(!decomponly) { if(loadbmp(argv[1], &srcbuf, &w, &h, pf, (flags&TJFLAG_BOTTOMUP)!=0)==-1) _throwbmp("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\tBitmap\tJPEG\tJPEG\t%s %s \tComp\tComp\tDecomp\n", dotile? "Tile ":"Image", dotile? "Tile ":"Image"); printf("Format\tOrder\tSubsamp\tQual\tWidth Height\tPerf \tRatio\tPerf\n\n"); } if(decomponly) { dodecomptest(argv[1]); printf("\n"); goto bailout; } for(i=maxqual; i>=minqual; i--) dotest(srcbuf, w, h, TJ_GRAYSCALE, i, argv[1]); printf("\n"); for(i=maxqual; i>=minqual; i--) dotest(srcbuf, w, h, TJ_420, i, argv[1]); printf("\n"); for(i=maxqual; i>=minqual; i--) dotest(srcbuf, w, h, TJ_422, i, argv[1]); printf("\n"); for(i=maxqual; i>=minqual; i--) dotest(srcbuf, w, h, TJ_444, i, argv[1]); printf("\n"); bailout: if(srcbuf) free(srcbuf); return retval; }
int main(int argc, char *argv[]) { unsigned char *srcbuf=NULL; int w=0, h=0, i, j; int minqual=-1, maxqual=-1; char *temp; int minarg=2, retval=0, subsamp=-1; if((scalingfactors=tjGetScalingFactors(&nsf))==NULL || nsf==0) _throwtj("executing tjGetScalingFactors()"); 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; } if(!strcasecmp(argv[i], "-fastupsample")) { printf("Using fast upsampling code\n\n"); flags|=TJFLAG_FASTUPSAMPLE; } if(!strcasecmp(argv[i], "-fastdct")) { printf("Using fastest DCT/IDCT algorithm\n\n"); flags|=TJFLAG_FASTDCT; } if(!strcasecmp(argv[i], "-accuratedct")) { printf("Using most accurate DCT/IDCT algorithm\n\n"); flags|=TJFLAG_ACCURATEDCT; } if(!strcasecmp(argv[i], "-rgb")) pf=TJPF_RGB; if(!strcasecmp(argv[i], "-rgbx")) pf=TJPF_RGBX; if(!strcasecmp(argv[i], "-bgr")) pf=TJPF_BGR; if(!strcasecmp(argv[i], "-bgrx")) pf=TJPF_BGRX; if(!strcasecmp(argv[i], "-xbgr")) pf=TJPF_XBGR; if(!strcasecmp(argv[i], "-xrgb")) pf=TJPF_XRGB; if(!strcasecmp(argv[i], "-cmyk")) pf=TJPF_CMYK; if(!strcasecmp(argv[i], "-bottomup")) flags|=TJFLAG_BOTTOMUP; if(!strcasecmp(argv[i], "-quiet")) quiet=1; if(!strcasecmp(argv[i], "-qq")) quiet=2; 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]); } if(!strcasecmp(argv[i], "-hflip")) xformop=TJXOP_HFLIP; if(!strcasecmp(argv[i], "-vflip")) xformop=TJXOP_VFLIP; if(!strcasecmp(argv[i], "-transpose")) xformop=TJXOP_TRANSPOSE; if(!strcasecmp(argv[i], "-transverse")) xformop=TJXOP_TRANSVERSE; if(!strcasecmp(argv[i], "-rot90")) xformop=TJXOP_ROT90; if(!strcasecmp(argv[i], "-rot180")) xformop=TJXOP_ROT180; if(!strcasecmp(argv[i], "-rot270")) xformop=TJXOP_ROT270; if(!strcasecmp(argv[i], "-grayscale")) xformopt|=TJXOPT_GRAY; if(!strcasecmp(argv[i], "-custom")) customFilter=dummyDCTFilter; if(!strcasecmp(argv[i], "-nooutput")) xformopt|=TJXOPT_NOOUTPUT; if(!strcasecmp(argv[i], "-benchtime") && i<argc-1) { double temp=atof(argv[++i]); if(temp>0.0) benchtime=temp; else usage(argv[0]); } if(!strcasecmp(argv[i], "-warmup") && i<argc-1) { int temp=atoi(argv[++i]); if(temp>=0) { warmup=temp; printf("Warmup runs = %d\n\n", warmup); } else usage(argv[0]); } if(!strcmp(argv[i], "-?")) usage(argv[0]); if(!strcasecmp(argv[i], "-alloc")) flags&=(~TJFLAG_NOREALLOC); if(!strcasecmp(argv[i], "-bmp")) ext="bmp"; if(!strcasecmp(argv[i], "-yuv")) { printf("Testing YUV planar encoding/decoding\n\n"); doyuv=1; } if(!strcasecmp(argv[i], "-yuvpad") && i<argc-1) { int temp=atoi(argv[++i]); if(temp>=1) yuvpad=temp; } 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; } } } if(!strcasecmp(argv[i], "-componly")) componly=1; } } 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(loadbmp(argv[1], &srcbuf, &w, &h, pf, (flags&TJFLAG_BOTTOMUP)!=0)==-1) _throwbmp("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) free(srcbuf); return retval; }