CompressorTurboJPEG::~CompressorTurboJPEG() { if( _decoder ) tjDestroy( _decoder ); _decoder = 0; if( _encoder ) tjDestroy( _encoder ); _encoder = 0; }
static int do_decompress(unsigned char* comp_data, int comp_data_bytes, int* width, int* height, int bpp, unsigned char* decomp_data, int format) { tjhandle handle; int lwidth; int lheight; int jpeg_sub_samp; int rv; /* init decompression engine */ handle = tjInitDecompress(); /* get info about jpeg image */ rv = tjDecompressHeader2( handle, comp_data, comp_data_bytes, &lwidth, &lheight, &jpeg_sub_samp ); if (rv) { tjDestroy(handle); return rv; } /* decompress image */ rv = tjDecompress2( handle, comp_data, /* buffer containing JPEG image to decompress */ comp_data_bytes, /* size of JPEG image in bytes */ decomp_data, /* destination buffer for decompressed data */ lwidth, /* image width */ lwidth * (bpp / 8), /* pitch */ lheight, /* height of image */ format, /* pixel format TJPF_RGB, TJPF_XBGR */ 0 /* bitwise OR of one or more flags */ ); *width = lwidth; *height = lheight; /* deinit decompression engine */ tjDestroy(handle); return rv; }
void controlGraph::_onGotAFrame(QByteArray frame) { if(framerBusy) { qDebug() << "frame skipped - busy!"; } framerBusy = true; qDebug() << "got new frame: " << frame.size(); long unsigned int _jpegSize = frame.size(); //!< _jpegSize from above unsigned char* _compressedImage = (unsigned char*)frame.data(); //!< _compressedImage from above int jpegSubsamp, width, height; tjhandle _jpegDecompressor = tjInitDecompress(); tjDecompressHeader2(_jpegDecompressor, _compressedImage, _jpegSize, &width, &height, &jpegSubsamp); qDebug() << "size: " << width << "x" << height; qDebug() << "subsamp: " << jpegSubsamp; if(jpegSubsamp < 0 || (width != 640 && width != 960)) { qDebug() << "corrupted frame"; tjDestroy(_jpegDecompressor); framerBusy = false; return; } // int targetWidth = this->width(); // int targetHeight = height * (float)targetWidth / width; // qDebug() << "target size: " << targetWidth << "x" << targetHeight; free(currentFrameBuffer); currentFrameBuffer = (unsigned char*)malloc(width*height*tjPixelSize[TJPF_RGB]); int res = tjDecompress2(_jpegDecompressor, _compressedImage, _jpegSize, currentFrameBuffer, width, 0 /*pitch*/, height, TJPF_RGB, TJFLAG_FASTDCT); // qDebug() << "tjDecompress2: " << res; tjDestroy(_jpegDecompressor); QImage i(currentFrameBuffer, width, height, QImage::Format_RGB888); // i.save("/Users/korytov/2/_out.jpg", "JPEG"); if(i.width() != this->width()) { // qDebug() << "scaling to viewport: " << i.width() << " -> " << this->width(); i = i.scaled(this->width(), this->height()); } lvSnapshot.setPicture(&i); framerBusy = false; }
ofxTurboJpeg::~ofxTurboJpeg() { if (handleCompress) { tjDestroy(handleCompress); } if (handleDecompress) { tjDestroy(handleDecompress); } handleCompress = NULL; handleDecompress = NULL; }
FrameGrabber::~FrameGrabber() { #ifdef LIVRE_USE_LIBJPEGTURBO if( _compressor ) tjDestroy(_compressor); #endif }
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; }
bool TurboJpegReaderPlugin::getRegionOfDefinition( const OFX::RegionOfDefinitionArguments& args, OfxRectD& rod ) { try { FILE *file = NULL; unsigned char *jpegbuf = NULL; unsigned long jpgbufsize = 0; file = fopen( getAbsoluteFilenameAt( args.time ).c_str(), "rb" ); if( file == NULL ) { BOOST_THROW_EXCEPTION( exception::File() << exception::user( "TurboJpeg: Unable to open file" ) << exception::filename( getAbsoluteFilenameAt( args.time ) ) ); } fseek( file, 0, SEEK_END ); jpgbufsize = ftell( file ); jpegbuf = new unsigned char[ jpgbufsize ]; fseek(file, 0, SEEK_SET); fread( jpegbuf, jpgbufsize, 1, file ); const tjhandle jpeghandle = tjInitDecompress(); int width = 0; int height = 0; int jpegsubsamp = -1; int ret = tjDecompressHeader2( jpeghandle, jpegbuf, jpgbufsize, &width, &height, &jpegsubsamp ); if( ret != 0 ) { BOOST_THROW_EXCEPTION( exception::FileNotExist() << exception::user( tjGetErrorStr() ) << exception::filename( getAbsoluteFilenameAt( args.time ) ) ); } tjDestroy( jpeghandle ); //free(jpegbuf); delete[] jpegbuf; jpegbuf = NULL; fclose(file); file=NULL; rod.x1 = 0; rod.x2 = width * this->_clipDst->getPixelAspectRatio(); rod.y1 = 0; rod.y2 = height; //TUTTLE_COUT_VAR( rod ); } catch( std::exception& e ) { BOOST_THROW_EXCEPTION( exception::FileNotExist() << exception::user( "TurboJpeg: Unable to open file" ) << exception::filename( getAbsoluteFilenameAt( args.time ) ) ); } return true; }
HL_PRIM bool HL_NAME(jpg_decode)( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags ) { tjhandle h = tjInitDecompress(); int result; result = tjDecompress2(h,data,dataLen,out,width,stride,height,format,(flags & 1 ? TJFLAG_BOTTOMUP : 0)); tjDestroy(h); return result == 0; }
void BEJPEG::decompress ( void ) { read_header(); tjhandle jpeg_decompressor = tjInitDecompress(); if ( NULL != jpeg_decompressor ) { std::vector<unsigned char> decompressed_image ( width * height * tjPixelSize[pixel_format] ); if ( data.size() > 0) { int error = tjDecompress2 ( jpeg_decompressor, &data[0], data.size(), &decompressed_image[0], width, 0, height, pixel_format, 0 ); tjDestroy ( jpeg_decompressor ); // error = if ( 0 == error ) { data = decompressed_image; } else { throw BEPlugin_Exception ( kJPEGDecompressionError, tjGetErrorStr() ); } } else { throw BEPlugin_Exception ( kErrorParameterMissing ); } } else { throw BEPlugin_Exception ( kJPEGInitDecompressorError, tjGetErrorStr() ); } }
void BEJPEG::read_header ( void ) { int image_width = 0; int image_height = 0; tjhandle jpeg_decompressor = tjInitDecompress(); if ( NULL != jpeg_decompressor ) { if ( data.size() > 0) { int error = tjDecompressHeader3 ( jpeg_decompressor, &data[0], data.size(), &image_width, &image_height, &chrominance_subsampling, &pixel_format ); tjDestroy(jpeg_decompressor); // error = if ( 0 == error ) { adjust_dimensions ( image_width, image_height ); } else { throw BEPlugin_Exception ( kJPEGReadHeaderError, tjGetErrorStr() ); } } else { throw BEPlugin_Exception ( kErrorParameterMissing ); } } else { throw BEPlugin_Exception ( kJPEGInitDecompressorError, tjGetErrorStr() ); } }
V4Linux2Camera::~V4Linux2Camera(void) { CameraTool::saveSettings(); if ((pixelformat == V4L2_PIX_FMT_MJPEG) || (pixelformat == V4L2_PIX_FMT_JPEG)) tjDestroy(_jpegDecompressor); if (cam_buffer!=NULL) delete []cam_buffer; cam_buffer = NULL; if (frm_buffer!=NULL) delete []frm_buffer; frm_buffer = NULL; }
// Drop-in replacement for stbi_load_from_memory(), but without component specification. // Often 2x - 3x faster. unsigned char * TurboJpegLoadFromMemory( const unsigned char * jpg, const int length, int * width, int * height ) { tjhandle tj = tjInitDecompress(); int jpegWidth; int jpegHeight; int jpegSubsamp; int jpegColorspace; const int headerRet = tjDecompressHeader3( tj, ( unsigned char * )jpg /* tj isn't const correct */, length, &jpegWidth, &jpegHeight, &jpegSubsamp, &jpegColorspace ); if ( headerRet ) { LOG_TJ( "TurboJpegLoadFromMemory: header: %s", tjGetErrorStr() ); tjDestroy( tj ); return NULL; } const int bufLen = jpegWidth * jpegHeight * 4; unsigned char * buffer = ( unsigned char * )malloc( bufLen ); if ( buffer != NULL ) { const int decompRet = tjDecompress2( tj, ( unsigned char * )jpg, length, buffer, jpegWidth, jpegWidth * 4, jpegHeight, TJPF_RGBX, 0 /* flags */ ); if ( decompRet ) { LOG_TJ( "TurboJpegLoadFromMemory: decompress: %s", tjGetErrorStr() ); tjDestroy( tj ); free( buffer ); return NULL; } tjDestroy( tj ); *width = jpegWidth; *height = jpegHeight; } return buffer; }
void DepthImageBase::setColorData(uchar *srcData, int srcSize) { tjhandle dhandle = tjInitDecompress(); if(dhandle == NULL) return; int width = 0, height = 0; int jpegSubsamp; int flag = tjDecompressHeader2( dhandle, srcData, srcSize, &width, &height, &jpegSubsamp ); if(flag == -1) { tjDestroy(dhandle); return; } if(mColorSize != width * height * 3) reSizeColor(width * height * 3); flag = tjDecompress2( dhandle, srcData, srcSize, mColor, width, tjPixelSize[TJPF_RGB]*width, height, TJPF_RGB, TJFLAG_BOTTOMUP ); tjDestroy(dhandle); if(flag == -1) return; LOGI("JPEG %d*%d", width, height); mCflag = true; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy (JNIEnv *env, jobject obj) { tjhandle handle=0; gethandle(); if(tjDestroy(handle)==-1) _throw(tjGetErrorStr()); (*env)->SetLongField(env, obj, _fid, 0); bailout: return; }
PixelStream::~PixelStream() { // delete bound texture if(textureBound_ == true) { // let the OpenGL window delete the texture, so the destructor can occur in any thread... g_mainWindow->getGLWindow()->insertPurgeTextureId(textureId_); textureBound_ = false; } // destroy libjpeg-turbo handle tjDestroy(handle_); }
// Drop-in replacement for stbi_load_from_memory(), but without component specification. // Often 2x - 3x faster. unsigned char * TurboJpegLoadFromMemory( const unsigned char * jpg, const int length, int * width, int * height ) { tjhandle tj = tjInitDecompress(); int jpegWidth; int jpegHeight; int jpegSubsamp; int jpegColorspace; const int headerRet = tjDecompressHeader3( tj, ( unsigned char * )jpg /* tj isn't const correct */, length, &jpegWidth, &jpegHeight, &jpegSubsamp, &jpegColorspace ); if ( headerRet ) { LOG( "TurboJpegLoadFromMemory: header: %s", tjGetErrorStr() ); tjDestroy( tj ); return NULL; } MemBuffer tjb( jpegWidth * jpegHeight * 4 ); const int decompRet = tjDecompress2( tj, ( unsigned char * )jpg, length, ( unsigned char * )tjb.Buffer, jpegWidth, jpegWidth * 4, jpegHeight, TJPF_RGBX, 0 /* flags */ ); if ( decompRet ) { LOG( "TurboJpegLoadFromMemory: decompress: %s", tjGetErrorStr() ); tjDestroy( tj ); tjb.FreeData(); return NULL; } tjDestroy( tj ); *width = jpegWidth; *height = jpegHeight; return ( unsigned char * )tjb.Buffer; }
static Shared<Buffer> save_to_buffer(const LayoutT & layout, const Byte * input, int format, std::uint32_t quality) { std::size_t output_size = 0; Byte * output_data = NULL; //!< Memory is allocated by tjCompress2 if _jpegSize == 0 tjhandle compressor = tjInitCompress(); tjCompress2(compressor, input, static_cast<int>(layout.size[WIDTH]), static_cast<int>(layout.stride[0]), static_cast<int>(layout.size[HEIGHT]), TJPF_RGBX, &output_data, &output_size, TJSAMP_444, quality, TJFLAG_FASTDCT); tjDestroy(compressor); if (output_data) { return shared<ForeignBuffer<Byte, tjFree>>(output_data, output_size); } else { return nullptr; } }
int JPEGConverter::decode_frame2(const char *buffer, int length, unsigned char *samples) { long unsigned int _jpegSize = length; //!< _jpegSize from above unsigned char* _compressedImage = (unsigned char *)buffer; //!< _compressedImage from above int jpegSubsamp, width, height; //unsigned char buffer[width*height*COLOR_COMPONENTS]; //!< will contain the decompressed image tjhandle _jpegDecompressor = tjInitDecompress(); tjDecompressHeader2(_jpegDecompressor, _compressedImage, _jpegSize, &width, &height, &jpegSubsamp); //tjDecompress2(_jpegDecompressor, _compressedImage, _jpegSize, samples, width, 0/*pitch*/, height, TJPF_RGB, TJFLAG_FASTDCT); tjDecompress2(_jpegDecompressor, _compressedImage, _jpegSize, samples, width, 0/*pitch*/, height, TJPF_BGR, TJFLAG_FASTDCT); tjDestroy(_jpegDecompressor); return width*height*3; }
void readJPEG(const std::string &fullpath, unsigned char* &rgbdata, int &width, int &height) { FILE* fp = fopen(fullpath.c_str(),"rb"); fseek(fp,0,SEEK_END); size_t flen = ftell(fp); fseek(fp,0,SEEK_SET); unsigned char *jpegdata = (unsigned char*)malloc( flen ); fread(jpegdata,flen,1,fp); fclose(fp); int jpegSubsamp=0; tjhandle _jpegDecompressor = tjInitDecompress(); tjDecompressHeader2(_jpegDecompressor, jpegdata, flen, &width, &height, &jpegSubsamp); rgbdata =(unsigned char*) malloc( width * height * 3); tjDecompress2(_jpegDecompressor, jpegdata, flen, rgbdata, width, 0/*pitch*/, height, TJPF_RGB, TJFLAG_FASTDCT); free(jpegdata); tjDestroy(_jpegDecompressor); }
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 ); }
/* mind thread */ void *mind_thread(void *arg) { unsigned char *frame = (unsigned char *) calloc(1, (size_t) cd.videoIn->framesizeIn); unsigned char *pixmap = (unsigned char *) calloc(1, (size_t) cd.videoIn->framesizeIn); int frame_size = 0; int jpegss; tjhandle jtd; struct v_frame vframe; printf("Start thread\n"); vframe.pixmap = (unsigned int *) pixmap; jtd = tjInitDecompress(); while (!stop) { /* wait for fresh frames */ pthread_cond_wait(&db_update, &db); /* read buffer */ frame_size = g_size; memcpy(frame, g_buf, frame_size); pthread_mutex_unlock(&db); tjDecompressHeader2(jtd, frame, frame_size, &(vframe.w), &(vframe.h), &jpegss); tjBufSizeYUV(vframe.w, vframe.h, jpegss); tjDecompressToYUV(jtd, frame, frame_size, pixmap, 0); if (jpegss != TJSAMP_422) { printf("Failed: Chrominance subsampling options is %d. \n", jpegss); continue; } vision_frame(&vframe); } tjDestroy(jtd); free(frame); free(pixmap); return NULL; }
void jpegStream::decodeImage(image * img) { compressedImage * compImg = imgStreamer->capture(); if(compImg) { unsigned char * buff = compImg->buffer; unsigned int len = compImg->bufLen; tjhandle tj = tjInitDecompress(); int width, height, samp; tjDecompressHeader2(tj, buff, len, &width, &height, &samp); img->x = width; img->y = height; //std::cout << "image dims : " << img->x << ", " << img->y << "\n"; img->pixels = new pixel[img->x * img->y]; tjDecompress2(tj, buff, len, (unsigned char *)img->pixels, width, 0, height, TJPF_RGB, TJFLAG_FASTDCT); tjDestroy(tj); } else { std::cout << "ERROR : IMAGE STREAM FAILED\n"; } }
void BEJPEG::compress ( void ) { tjhandle jpeg_compressor = tjInitCompress(); if ( NULL != jpeg_compressor ) { unsigned long image_size = width * height * tjPixelSize[pixel_format]; std::vector<unsigned char> image ( image_size ); unsigned char * compressed_image = &image[0]; int error = tjCompress2 ( jpeg_compressor, &data[0], width, 0, height, pixel_format, &compressed_image, &image_size, chrominance_subsampling, compression_level, 0 ); tjDestroy ( jpeg_compressor ); // error = if ( 0 == error ) { image.resize ( image_size ); data = image; } else { throw BEPlugin_Exception ( kJPEGCompressionError, tjGetErrorStr() ); } } else { throw BEPlugin_Exception ( kJPEGInitCcompressorError, tjGetErrorStr() ); } }
// Given a filename and an image object, it loads the file with that name into // the object. void loadImage(Image *image, char* filename) { FILE* jpegfile = fopen(filename, "rb"); if(jpegfile == NULL) { EPRINT("Error: Unable to open file!\n"); exit(-1); } struct stat stbuf; if ((fstat(fileno(jpegfile), &stbuf) != 0) || (!S_ISREG(stbuf.st_mode))) { EPRINT("Error: Unable to determine file size!\n"); exit(-1); } off_t filesize = stbuf.st_size; unsigned char* buffer = malloc(filesize); if (buffer == NULL) { EPRINT("Error: Unable to allocate memory for jpeg!\n"); exit(-1); } if(fread(buffer, 1, filesize, jpegfile) != filesize) { EPRINT("Error: Unable to read file!\n"); exit(-1); } fclose(jpegfile); tjhandle decomp; if(!(decomp = tjInitDecompress())) { EPRINT("Error: Unable to initialize TurboJPEG decompressor!\n"); EPRINT("%s\n", tjGetErrorStr()); exit(-1); } int width, height, jpegSubsamp, jpegColorspace; if(tjDecompressHeader3(decomp, buffer, filesize, &width, &height, &jpegSubsamp, &jpegColorspace)) { EPRINT("Error: Unable to read JPEG header!\n"); EPRINT("%s\n", tjGetErrorStr()); exit(-1); } image->width = width; image->height = height; unsigned long decompressed_size; decompressed_size = width*height*tjPixelSize[PIXEL_FORMAT]; unsigned char* buffer2 = malloc(decompressed_size); if(tjDecompress2(decomp, buffer, filesize, buffer2, width, width * tjPixelSize[PIXEL_FORMAT], height, PIXEL_FORMAT, TJFLAG_NOREALLOC)) { EPRINT("Error: Unable to decompress JPEG image!\n"); EPRINT("%s\n", tjGetErrorStr()); exit(-1); } // Free up some memory since we are done with image decoding tjDestroy(decomp); free(buffer); assert(tjPixelSize[PIXEL_FORMAT] == sizeof(Pixel)); image->data = (Pixel *) buffer2; return; }
LibraryInitParams::~LibraryInitParams() { tjDestroy(TurboJpegCompressor); libusb_exit(UsbContext); }
void dodecomptest(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, _w, _h, _tilew, _tileh, _ntilesw, _ntilesh, _subsamp; char *temp=NULL, tempstr[80], tempstr2[80]; int row, col, i, tilew, tileh, ntilesw, ntilesh, 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))<0) _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(tjDecompressHeader2(handle, srcbuf, srcsize, &w, &h, &subsamp)==-1) _throwtj("executing tjDecompressHeader2()"); if(quiet==1) { printf("All performance values in Mpixels/sec\n\n"); printf("Bitmap\tBitmap\tJPEG\t%s %s \tXform\tComp\tDecomp\n", dotile? "Tile ":"Image", dotile? "Tile ":"Image"); printf("Format\tOrder\tSubsamp\tWidth Height\tPerf \tRatio\tPerf\n\n"); } else if(!quiet) { printf(">>>>> JPEG %s --> %s (%s) <<<<<\n", subNameLong[subsamp], 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) for(i=0; i<ntilesw*ntilesh; i++) { if((jpegbuf[i]=(unsigned char *)malloc(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("%s\t%s\t%s\t", pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "BU":"TD", subNameLong[subsamp]); printf("%-4d %-4d\t", tilew, tileh); } _subsamp=subsamp; if(dotile || xformop!=TJXOP_NONE || xformopt!=0) { 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; 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; } } start=gettime(); if(tjTransform(handle, srcbuf, srcsize, _ntilesw*_ntilesh, jpegbuf, jpegsize, t, flags)==-1) _throwtj("executing tjTransform()"); elapsed=gettime()-start; free(t); t=NULL; for(tile=0, totaljpegsize=0; tile<_ntilesw*_ntilesh; tile++) totaljpegsize+=jpegsize[tile]; if(quiet) { printf("%s%c%s%c", sigfig((double)(w*h)/1000000./elapsed, 4, tempstr, 80), quiet==2? '\n':'\t', sigfig((double)(w*h*ps)/(double)totaljpegsize, 4, tempstr2, 80), quiet==2? '\n':'\t'); } else if(!quiet) { printf("X--> 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(" Source 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\tN/A\t"); jpegsize[0]=srcsize; memcpy(jpegbuf[0], srcbuf, srcsize); } if(w==tilew) _tilew=_w; if(h==tileh) _tileh=_h; if(decomptest(NULL, jpegbuf, jpegsize, NULL, _w, _h, _subsamp, 0, filename, _tilew, _tileh)==-1) goto bailout; for(i=0; i<ntilesw*ntilesh; i++) { free(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]) free(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; }
/* Decompression test */ int decomptest(unsigned char *srcbuf, unsigned char **jpegbuf, unsigned long *jpegsize, unsigned char *dstbuf, int w, int h, int subsamp, int jpegqual, char *filename, int tilew, int tileh) { char tempstr[1024], sizestr[20]="\0", qualstr[6]="\0", *ptr; FILE *file=NULL; tjhandle handle=NULL; int row, col, i, dstbufalloc=0, retval=0; double start, elapsed; int ps=tjPixelSize[pf]; int yuvsize=tjBufSizeYUV(w, h, subsamp), bufsize; int scaledw=(yuv==YUVDECODE)? w : TJSCALED(w, sf); int scaledh=(yuv==YUVDECODE)? h : TJSCALED(h, sf); int pitch=scaledw*ps; int ntilesw=(w+tilew-1)/tilew, ntilesh=(h+tileh-1)/tileh; unsigned char *dstptr, *dstptr2; if(jpegqual>0) { snprintf(qualstr, 6, "_Q%d", jpegqual); qualstr[5]=0; } if((handle=tjInitDecompress())==NULL) _throwtj("executing tjInitDecompress()"); bufsize=(yuv==YUVDECODE? yuvsize:pitch*h); if(dstbuf==NULL) { if((dstbuf=(unsigned char *)malloc(bufsize)) == NULL) _throwunix("allocating image buffer"); dstbufalloc=1; } /* Set the destination buffer to gray so we know whether the decompressor attempted to write to it */ memset(dstbuf, 127, bufsize); /* Execute once to preload cache */ if(yuv==YUVDECODE) { if(tjDecompressToYUV(handle, jpegbuf[0], jpegsize[0], dstbuf, flags)==-1) _throwtj("executing tjDecompressToYUV()"); } else if(tjDecompress2(handle, jpegbuf[0], jpegsize[0], dstbuf, scaledw, pitch, scaledh, pf, flags)==-1) _throwtj("executing tjDecompress2()"); /* Benchmark */ for(i=0, start=gettime(); (elapsed=gettime()-start)<benchtime; i++) { int tile=0; if(yuv==YUVDECODE) { if(tjDecompressToYUV(handle, jpegbuf[0], jpegsize[0], dstbuf, flags)==-1) _throwtj("executing tjDecompressToYUV()"); } else for(row=0, dstptr=dstbuf; row<ntilesh; row++, dstptr+=pitch*tileh) { for(col=0, dstptr2=dstptr; col<ntilesw; col++, tile++, dstptr2+=ps*tilew) { int width=dotile? min(tilew, w-col*tilew):scaledw; int height=dotile? min(tileh, h-row*tileh):scaledh; if(tjDecompress2(handle, jpegbuf[tile], jpegsize[tile], dstptr2, width, pitch, height, pf, flags)==-1) _throwtj("executing tjDecompress2()"); } } } if(tjDestroy(handle)==-1) _throwtj("executing tjDestroy()"); handle=NULL; if(quiet) { printf("%s\n", sigfig((double)(w*h)/1000000.*(double)i/elapsed, 4, tempstr, 1024)); } else { printf("D--> Frame rate: %f fps\n", (double)i/elapsed); printf(" Dest. throughput: %f Megapixels/sec\n", (double)(w*h)/1000000.*(double)i/elapsed); } if(yuv==YUVDECODE) { snprintf(tempstr, 1024, "%s_%s%s.yuv", filename, subName[subsamp], qualstr); if((file=fopen(tempstr, "wb"))==NULL) _throwunix("opening YUV image for output"); if(fwrite(dstbuf, yuvsize, 1, file)!=1) _throwunix("writing YUV image"); fclose(file); file=NULL; } else { if(sf.num!=1 || sf.denom!=1) snprintf(sizestr, 20, "%d_%d", sf.num, sf.denom); else if(tilew!=w || tileh!=h) snprintf(sizestr, 20, "%dx%d", tilew, tileh); else snprintf(sizestr, 20, "full"); if(decomponly) snprintf(tempstr, 1024, "%s_%s.%s", filename, sizestr, ext); else snprintf(tempstr, 1024, "%s_%s%s_%s.%s", filename, subName[subsamp], qualstr, sizestr, ext); if(savebmp(tempstr, dstbuf, scaledw, scaledh, pf, (flags&TJFLAG_BOTTOMUP)!=0)==-1) _throwbmp("saving bitmap"); ptr=strrchr(tempstr, '.'); snprintf(ptr, 1024-(ptr-tempstr), "-err.%s", ext); if(srcbuf && sf.num==1 && sf.denom==1) { if(!quiet) printf("Compression error written to %s.\n", tempstr); if(subsamp==TJ_GRAYSCALE) { int index, index2; for(row=0, index=0; row<h; row++, index+=pitch) { for(col=0, index2=index; col<w; col++, index2+=ps) { int rindex=index2+tjRedOffset[pf]; int gindex=index2+tjGreenOffset[pf]; int bindex=index2+tjBlueOffset[pf]; int y=(int)((double)srcbuf[rindex]*0.299 + (double)srcbuf[gindex]*0.587 + (double)srcbuf[bindex]*0.114 + 0.5); if(y>255) y=255; if(y<0) y=0; dstbuf[rindex]=abs(dstbuf[rindex]-y); dstbuf[gindex]=abs(dstbuf[gindex]-y); dstbuf[bindex]=abs(dstbuf[bindex]-y); } } } else { for(row=0; row<h; row++) for(col=0; col<w*ps; col++) dstbuf[pitch*row+col] =abs(dstbuf[pitch*row+col]-srcbuf[pitch*row+col]); } if(savebmp(tempstr, dstbuf, w, h, pf, (flags&TJFLAG_BOTTOMUP)!=0)==-1) _throwbmp("saving bitmap"); } } bailout: if(file) {fclose(file); file=NULL;} if(handle) {tjDestroy(handle); handle=NULL;} if(dstbuf && dstbufalloc) {free(dstbuf); dstbuf=NULL;} return retval; }
~TjComp() { tjDestroy(handle); }
/* * Main Documentation: * http://www.libjpeg-turbo.org/Documentation/Documentation * See C API * * * Functions Used: * tjDecompressHeader2 * tjDecompress2 */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { //Calling form: //img_data = readJPG(uncompressed_image_data); // // INPUTS // ------------------------------------------------ // uncompressed_image_data: (uint8 array) // // // Documentation // http://libjpeg-turbo.sourceforge.net/ljtdoc.branches_1.3.x/turbojpeg-c/group___turbo_j_p_e_g.html uint8_T* buffer; unsigned char* compressed_image; int compressed_image_size; mwSize dims[3] = {0,0,0}; int width; int height; int pixel_format; int flags; int is_3d; int option; int jpeg_subsamp; tjhandle jpeg_decompressor; //Input Checking //--------------------------------------------------------------------- if (nrhs != 2) { mexErrMsgTxt("2 inputs needed, readJPGHelper(u8_data,option)"); }else if (!mxIsUint8(prhs[0])) { mexErrMsgTxt("Input data type must be uint8"); } //Input Retrieval //--------------------------------------------------------------------- compressed_image = (unsigned char *)mxGetData(prhs[0]); compressed_image_size = (int)mxGetNumberOfElements(prhs[0]); option = (int)mxGetScalar(prhs[1]); switch (option) { case 1: //fast RGB flags = TJFLAG_FASTDCT; pixel_format = TJPF_RGB; is_3d = 1; break; case 2: //slow RGB flags = 0; pixel_format = TJPF_RGB; is_3d = 1; break; case 3: //fast gray flags = TJFLAG_FASTDCT; pixel_format = TJPF_GRAY; is_3d = 0; break; case 4: //slow gray flags = 0; pixel_format = TJPF_GRAY; is_3d = 0; break; default: mexErrMsgTxt("Invalid input option"); break; } jpeg_decompressor = tjInitDecompress(); //Retrieve image information, namely width and height //tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp // // NOTE: This might change for 1.4 ... to tjDecompressHeader3 with color type included tjDecompressHeader2(jpeg_decompressor, compressed_image, compressed_image_size, &width, &height, &jpeg_subsamp); //NOTE, this might eventually change based on what we want out //-------------------------------------------- if (is_3d) { buffer = mxMalloc((width)*(height)*3); //*3 implies RGB }else{ buffer = mxMalloc((width)*(height)); } //mexPrintf("Width: %d\n",width); //mexPrintf("Height: %d\n",height); //mexPrintf("sub_samp: %d\n",jpeg_subsamp); //Last two inputs are flags and options //I'm not sure how to distinguish them, but the inputs are very different //After height: //1) pixel_format //2) flags // //Pixel Formats //--------------------------------------------------------------------- //TJPF_RGB - RGB //TJPF_GRAY // //Flags //--------------------------------------------------------------------- //TJFLAG_FASTDCT - used fastest IDCT algorithm //TJFLAG_FASTUPSAMPLE - not exposed // //TJXOPT_GRAY - discard color, produce gray tjDecompress2(jpeg_decompressor, compressed_image, compressed_image_size, buffer, width, 0, height, pixel_format, flags); //For gray, do I need to convery to YUV then grab tjDestroy(jpeg_decompressor); //Setup Output //------------------------------------------------------------------ if (is_3d) { plhs[0] = mxCreateNumericArray(3,&dims[0], mxUINT8_CLASS, mxREAL); mxSetData(plhs[0], buffer); dims[0] = 3; dims[1] = width; dims[2] = height; mxSetDimensions(plhs[0],&dims[0], 3); } else { plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT8_CLASS, mxREAL); mxSetData(plhs[0], buffer); mxSetM(plhs[0], width); mxSetN(plhs[0], height); } //OLD, single dimension only //------------------------------- //plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT8_CLASS, mxREAL); //mxSetM(plhs[0], width*height*3); //mxSetN(plhs[0], 1); }
ImageJpegCompressor::~ImageJpegCompressor() { tjDestroy(_tjHandle); }