diff --git a/turbojpeg-mapfile b/turbojpeg-mapfile index 5477fed2..4eae5b45 100644 --- a/turbojpeg-mapfile +++ b/turbojpeg-mapfile @@ -62,4 +62,5 @@ TURBOJPEG_2.0 tjGetErrorStr2; tjLoadImage; tjSaveImage; + tjCropDecompress2; } TURBOJPEG_1.4; diff --git a/turbojpeg.c b/turbojpeg.c index d780dc25..64bcf281 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -1276,6 +1276,98 @@ DLLEXPORT tjscalingfactor *tjGetScalingFactors(int *numscalingfactors) } +DLLEXPORT int tjCropDecompress2(tjhandle handle, const unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, + int flags, int crop_x, int crop_y, int crop_h, int crop_w) +{ + JSAMPROW *row_pointer = NULL; + int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; + struct my_progress_mgr progress; + + GET_DINSTANCE(handle); + this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; + if ((this->init & DECOMPRESS) == 0) + THROW("tjDecompress2(): Instance has not been initialized for decompression"); + + if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 || + pitch < 0 || height < 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF) + THROW("tjDecompress2(): Invalid argument"); + +#ifndef NO_PUTENV + if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); + else if (flags & TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); + else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); +#endif + + if (flags & TJFLAG_LIMITSCANS) { + memset(&progress, 0, sizeof(struct my_progress_mgr)); + progress.pub.progress_monitor = my_progress_monitor; + progress.this = this; + dinfo->progress = &progress.pub; + } else + dinfo->progress = NULL; + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + jpeg_read_header(dinfo, TRUE); + this->dinfo.out_color_space = pf2cs[pixelFormat]; + if (flags & TJFLAG_FASTDCT) this->dinfo.dct_method = JDCT_FASTEST; + if (flags & TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling = FALSE; + + jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; + if (width == 0) width = jpegwidth; + if (height == 0) height = jpegheight; + for (i = 0; i < NUMSF; i++) { + scaledw = TJSCALED(jpegwidth, sf[i]); + scaledh = TJSCALED(jpegheight, sf[i]); + if (scaledw <= width && scaledh <= height) + break; + } + if (i >= NUMSF) + THROW("tjCropDecompress2(): Could not scale down to desired image dimensions"); + width = scaledw; height = scaledh; + dinfo->scale_num = sf[i].num; + dinfo->scale_denom = sf[i].denom; + + jpeg_start_decompress(dinfo); + if (pitch == 0) pitch = crop_w * tjPixelSize[pixelFormat]; + + if ((row_pointer = + (JSAMPROW *)malloc(sizeof(JSAMPROW) * crop_h)) == NULL) + THROW("tjDecompress2(): Memory allocation failure"); + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + for (i = 0; i < crop_h; i++) { + if (flags & TJFLAG_BOTTOMUP) + row_pointer[i] = &dstBuf[(crop_h - i - 1) * (size_t)pitch]; + else + row_pointer[i] = &dstBuf[i * (size_t)pitch]; + } + //crop image + jpeg_crop_scanline(dinfo, &crop_y, &crop_w); + jpeg_skip_scanlines(dinfo, crop_x); + while (dinfo->output_scanline < dinfo->output_height && dinfo->output_scanline < crop_h + crop_x) + jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline-crop_x], + crop_x + crop_h - dinfo->output_scanline); + jpeg_skip_scanlines(dinfo, dinfo->output_height - dinfo->output_scanline); + jpeg_finish_decompress(dinfo); + +bailout: + if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); + free(row_pointer); + if (this->jerr.warning) retval = -1; + this->jerr.stopOnWarning = FALSE; + return retval; +} + + DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, diff --git a/turbojpeg.h b/turbojpeg.h index 5b33ad84..64b5e86c 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -1224,6 +1224,13 @@ DLLEXPORT tjscalingfactor *tjGetScalingFactors(int *numscalingfactors); * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() * and #tjGetErrorCode().) */ + +DLLEXPORT int tjCropDecompress2(tjhandle handle, const unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, + int flags, int crop_x, int crop_y,int crop_h, int crop_w); + + DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat,