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 JPEGImage::load(const PixelLayout<PixelFormat::BGR8> & layout, Byte * data) const { tjDecompress2( _decompressor, _data->begin(), _data->size(), data, static_cast<int>(layout.size[WIDTH]), static_cast<int>(layout.stride[0]), static_cast<int>(layout.size[HEIGHT]), TJPF_BGR, TJFLAG_FASTDCT ); }
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; }
std::unique_ptr<uint8_t[]> DecodeJpeg(const array_view<uint8_t> data) { TjDecompressHandle handle; int w, h; tjDecompressHeader(handle, &data[0], data.bytes(), &w, &h); std::unique_ptr<uint8_t[]> result(new uint8_t[w * h * 4]); auto status = tjDecompress2(handle, &data[0], data.bytes(), &result[0], w, w * 4, h, TJPF_BGRX, 0); if (status != 0) { throw TempleException("Unable to decompress jpeg image: {}", tjGetErrorStr()); } return result; }
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; }
void loadImageDataThread(boost::shared_ptr<PixelStream> pixelStream, QByteArray imageData) { // use libjpeg-turbo for JPEG conversion tjhandle handle = pixelStream->getHandle(); // get information from header int width, height, jpegSubsamp; int success = tjDecompressHeader2(handle, (unsigned char *)imageData.data(), (unsigned long)imageData.size(), &width, &height, &jpegSubsamp); if(success != 0) { put_flog(LOG_ERROR, "libjpeg-turbo header decompression failure"); return; } // decompress image data int pixelFormat = TJPF_BGRX; int pitch = width * tjPixelSize[pixelFormat]; int flags = TJ_FASTUPSAMPLE; QImage image = QImage(width, height, QImage::Format_RGB32); success = tjDecompress2(handle, (unsigned char *)imageData.data(), (unsigned long)imageData.size(), (unsigned char *)image.scanLine(0), width, pitch, height, pixelFormat, flags); if(success != 0) { put_flog(LOG_ERROR, "libjpeg-turbo image decompression failure"); return; } /* uint c = 0x0000ff00; int width=64; int height=64; QImage image = QImage(width, height, QImage::Format_RGB32); for (int i=0; i<height; i++) { for (int j=0; j<height; j++) image.setPixel(i,j,c); }*/ pixelStream->imageReady(image); }
void CRClient::handle_rreceive (const boost::system::error_code& error, std::size_t bytes_transferred) { std::cout << "IN" << std::endl; if (!error || error == boost::asio::error::message_size) { switch(recv_rbuffer.data()[ID]) { case CONNECT: connection = true; std::cout << "Connected ! Rendering is about to begin !!" << std::endl; break; case RENDER: std::cout << "Rendered Frame " << (int)(recv_rbuffer.data()[FRAME]) << std::endl; #if 0 { unsigned char* jpegstream = new unsigned char[(int)bytes_transferred-2]; unsigned long jpegsize = (unsigned long)(bytes_transferred - 2); // tjDecompressHeader2(jpeg, jpegstream, jpegsize, &width, &height, &subsamp); // int pitch = width * tjPixelSize[pixelformat]; unsigned char* data = new unsigned char [width*height*tjPixelSize[pixelformat]]; tjDecompress2(jpeg, jpegstream, jpegsize, data, width, pitch, height, pixelformat, flags); //QImage tempQimage(data,width,height,QImage::Format_RGBA8888); QImage tempQImage(data,width,height,QImage::Format_RGBA8888); myFrame->fromImage(tempQImage); //myFrame->fromImage(QImage::QImage(data,width,height,QImage::Format_RGBA8888)); delete [] jpegstream; } #endif qDebug() << "Emiting"; // emit updateFrameBuffer_signal(myFrame); qDebug() << "Emitted"; break; case EXIT: std::cout << "Exiting " << std::endl; return; default: std::cout << "Failed" << std::endl; break; } qDebug() << "Listen Again"; //rlisten (); } rlisten (); }
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; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags) { tjhandle handle=0; jsize arraySize=0, actualStride; unsigned char *jpegBuf=NULL, *dstBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF) _throw("Invalid argument in decompress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); if(tjPixelSize[pf]!=sizeof(jint)) _throw("Pixel format must be 32-bit when decompressing to an integer buffer."); if((*env)->GetArrayLength(env, src)<jpegSize) _throw("Source buffer is not large enough"); actualStride=(stride==0)? width:stride; arraySize=(y+height-1)*actualStride + x+width; if((*env)->GetArrayLength(env, dst)<arraySize) _throw("Destination buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint), height, pf, flags)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); dstBuf=jpegBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); return; }
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 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; }
// 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; }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) { tjhandle handle=0; jsize arraySize=0, actualPitch; unsigned char *jpegBuf=NULL, *dstBuf=NULL; gethandle(); if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF) _throw("Invalid argument in decompress()"); if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF) _throw("Mismatch between Java and C API"); if((*env)->GetArrayLength(env, src)<jpegSize) _throw("Source buffer is not large enough"); actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch; arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf]; if((*env)->GetArrayLength(env, dst)<arraySize) _throw("Destination buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf, flags)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); dstBuf=jpegBuf=NULL; _throw(tjGetErrorStr()); } bailout: if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); return; }
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"; } }
// 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; }
/* 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; }
unsigned char* V4Linux2Camera::getFrame() { if (dev_handle<0) return NULL; if (ioctl(dev_handle, VIDIOC_DQBUF, &v4l2_buf)<0) { running = false; return NULL; } unsigned char *raw_buffer = (unsigned char*)buffers[v4l2_buf.index].start; if (raw_buffer==NULL) return NULL; if(cfg->color) { if (cfg->frame) { if (pixelformat==V4L2_PIX_FMT_YUYV) crop_yuyv2rgb(cfg->cam_width,raw_buffer,frm_buffer); else if (pixelformat==V4L2_PIX_FMT_UYVY) crop_uyvy2rgb(cfg->cam_width,raw_buffer,frm_buffer); else if (pixelformat==V4L2_PIX_FMT_YUV420) { //TODO } else if (pixelformat==V4L2_PIX_FMT_YUV410) { //TODO } else if (pixelformat==V4L2_PIX_FMT_GREY) crop_gray2rgb(cfg->cam_width,raw_buffer, frm_buffer); else if ((pixelformat == V4L2_PIX_FMT_MJPEG) || (pixelformat == V4L2_PIX_FMT_JPEG)) { int jpegSubsamp; tjDecompressHeader2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, &cfg->cam_width, &cfg->cam_height, &jpegSubsamp); tjDecompress2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, cam_buffer, cfg->cam_width, 0, cfg->cam_height, TJPF_RGB, TJFLAG_FASTDCT); crop(cfg->cam_width, cfg->cam_height,cam_buffer,frm_buffer,3); } } else { if (pixelformat==V4L2_PIX_FMT_YUYV) yuyv2rgb(cfg->cam_width,cfg->cam_height,raw_buffer,cam_buffer); else if (pixelformat==V4L2_PIX_FMT_UYVY) uyvy2rgb(cfg->cam_width,cfg->cam_height,raw_buffer,cam_buffer); else if (pixelformat==V4L2_PIX_FMT_YUV420) { //TODO } else if (pixelformat==V4L2_PIX_FMT_YUV410) { //TODO } else if (pixelformat==V4L2_PIX_FMT_GREY) gray2rgb(cfg->cam_width,cfg->cam_height,raw_buffer,cam_buffer); else if ((pixelformat == V4L2_PIX_FMT_MJPEG) || (pixelformat == V4L2_PIX_FMT_JPEG)) { int jpegSubsamp; tjDecompressHeader2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, &cfg->cam_width, &cfg->cam_height, &jpegSubsamp); tjDecompress2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, cam_buffer, cfg->cam_width, 0, cfg->cam_height, TJPF_RGB, TJFLAG_FASTDCT); } } } else { if (cfg->frame) { if (pixelformat==V4L2_PIX_FMT_YUYV) crop_yuyv2gray(cfg->cam_width,raw_buffer,frm_buffer); else if (pixelformat==V4L2_PIX_FMT_UYVY) crop_uyvy2gray(cfg->cam_width,raw_buffer,frm_buffer); else if (pixelformat==V4L2_PIX_FMT_YUV420) crop(cfg->cam_width, cfg->cam_height,raw_buffer,frm_buffer,1); else if (pixelformat==V4L2_PIX_FMT_YUV410) crop(cfg->cam_width, cfg->cam_height,raw_buffer,frm_buffer,1); else if (pixelformat==V4L2_PIX_FMT_GREY) crop(cfg->cam_width, cfg->cam_height,raw_buffer,frm_buffer,1); else if ((pixelformat == V4L2_PIX_FMT_MJPEG) || (pixelformat == V4L2_PIX_FMT_JPEG)) { int jpegSubsamp; tjDecompressHeader2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, &cfg->cam_width, &cfg->cam_height, &jpegSubsamp); tjDecompress2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, cam_buffer, cfg->cam_width, 0, cfg->cam_height, TJPF_GRAY, TJFLAG_FASTDCT); crop(cfg->cam_width, cfg->cam_height,cam_buffer,frm_buffer,1); } } else { if (pixelformat==V4L2_PIX_FMT_YUYV) yuyv2gray(cfg->cam_width, cfg->cam_height, raw_buffer, cam_buffer); else if (pixelformat==V4L2_PIX_FMT_UYVY) uyvy2gray(cfg->cam_width, cfg->cam_height, raw_buffer, cam_buffer); else if (pixelformat==V4L2_PIX_FMT_YUV420) memcpy(cam_buffer,raw_buffer,cfg->cam_width*cfg->cam_height); else if (pixelformat==V4L2_PIX_FMT_YUV410) memcpy(cam_buffer,raw_buffer,cfg->cam_width*cfg->cam_height); //else if (pixelformat==V4L2_PIX_FMT_GREY) memcpy(cam_buffer,raw_buffer,cam_width*cam_height); else if ((pixelformat == V4L2_PIX_FMT_MJPEG) || (pixelformat == V4L2_PIX_FMT_JPEG)) { int jpegSubsamp; tjDecompressHeader2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, &cfg->cam_width, &cfg->cam_height, &jpegSubsamp); tjDecompress2(_jpegDecompressor, raw_buffer, v4l2_buf.bytesused, cam_buffer, cfg->cam_width, 0, cfg->cam_height, TJPF_GRAY, TJFLAG_FASTDCT); } } } if (-1 == ioctl (dev_handle, VIDIOC_QBUF, &v4l2_buf)) { printf("cannot unqueue buffer: %s\n", strerror(errno)); return NULL; } if (cfg->frame) return frm_buffer; else if ((!cfg->color) && (pixelformat==V4L2_PIX_FMT_GREY)) return raw_buffer; else return cam_buffer; }
/* Decompression test */ int decomp(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, iter=0, dstbufalloc=0, retval=0; double elapsed, elapsedDecode; int ps=tjPixelSize[pf]; int scaledw=TJSCALED(w, sf); int scaledh=TJSCALED(h, sf); int pitch=scaledw*ps; int ntilesw=(w+tilew-1)/tilew, ntilesh=(h+tileh-1)/tileh; unsigned char *dstptr, *dstptr2, *yuvbuf=NULL; if(jpegqual>0) { snprintf(qualstr, 6, "_Q%d", jpegqual); qualstr[5]=0; } if((handle=tjInitDecompress())==NULL) _throwtj("executing tjInitDecompress()"); if(dstbuf==NULL) { if((dstbuf=(unsigned char *)malloc(pitch*scaledh))==NULL) _throwunix("allocating destination buffer"); dstbufalloc=1; } /* Set the destination buffer to gray so we know whether the decompressor attempted to write to it */ memset(dstbuf, 127, pitch*scaledh); if(doyuv) { int width=dotile? tilew:scaledw; int height=dotile? tileh:scaledh; int yuvsize=tjBufSizeYUV2(width, yuvpad, height, subsamp); if((yuvbuf=(unsigned char *)malloc(yuvsize))==NULL) _throwunix("allocating YUV buffer"); memset(yuvbuf, 127, yuvsize); } /* Benchmark */ iter=-warmup; elapsed=elapsedDecode=0.; while(1) { int tile=0; double start=gettime(); 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(doyuv) { double startDecode; if(tjDecompressToYUV2(handle, jpegbuf[tile], jpegsize[tile], yuvbuf, width, yuvpad, height, flags)==-1) _throwtj("executing tjDecompressToYUV2()"); startDecode=gettime(); if(tjDecodeYUV(handle, yuvbuf, yuvpad, subsamp, dstptr2, width, pitch, height, pf, flags)==-1) _throwtj("executing tjDecodeYUV()"); if(iter>=0) elapsedDecode+=gettime()-startDecode; } else if(tjDecompress2(handle, jpegbuf[tile], jpegsize[tile], dstptr2, width, pitch, height, pf, flags)==-1) _throwtj("executing tjDecompress2()"); } } iter++; if(iter>=1) { elapsed+=gettime()-start; if(elapsed>=benchtime) break; } } if(doyuv) elapsed-=elapsedDecode; if(tjDestroy(handle)==-1) _throwtj("executing tjDestroy()"); handle=NULL; if(quiet) { printf("%-6s%s", sigfig((double)(w*h)/1000000.*(double)iter/elapsed, 4, tempstr, 1024), quiet==2? "\n":" "); if(doyuv) printf("%s\n", sigfig((double)(w*h)/1000000.*(double)iter/elapsedDecode, 4, tempstr, 1024)); else if(quiet!=2) printf("\n"); } else { printf("%s --> Frame rate: %f fps\n", doyuv? "Decomp to YUV":"Decompress ", (double)iter/elapsed); printf(" Throughput: %f Megapixels/sec\n", (double)(w*h)/1000000.*(double)iter/elapsed); if(doyuv) { printf("YUV Decode --> Frame rate: %f fps\n", (double)iter/elapsedDecode); printf(" Throughput: %f Megapixels/sec\n", (double)(w*h)/1000000.*(double)iter/elapsedDecode); } } 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); if(handle) tjDestroy(handle); if(dstbuf && dstbufalloc) free(dstbuf); if(yuvbuf) free(yuvbuf); return retval; }
int RactivJPEGDecompressor::decompress(unsigned char * in, unsigned long in_len, unsigned char * out, int width, int height) { tjDecompress2(handle, in, in_len, out, width, width * 3, height, TJPF_BGR, 0); return 0; }
// 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; }
/* * 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); }
bool JPEGReader::process_frame() { // Read from stream double timestamp; uint32_t length; this->fin->read((char*) ×tamp, sizeof(double)); if (this->fin->gcount() != sizeof(double)) { logger(panel, "jpeg", ERROR) << "Cannot read timestamp" << endl; return false; } this->fin->read((char*) &length, sizeof(uint32_t)); if (this->fin->gcount() != sizeof(uint32_t)) { logger(panel, "jpeg", ERROR) << "Cannot read length" << endl; return false; } length = ntohl(length); // See http://stackoverflow.com/a/30605295/807307 vector< char > buffer(length); this->fin->read(&buffer[0], length); if (this->fin->gcount() != length) { logger(panel, "jpeg", ERROR) << "Cannot read data" << endl; return false; } // Actually decode image FrameInfo info; int width, height, subsamp, res; res = tjDecompressHeader2(this->tj_dec, (unsigned char*) &buffer[0], length, &width, &height, &subsamp); if (res) { logger(panel, "jpeg", WARNING) << "Cannot decompress JPEG header, skipping frame" << endl; return true; } if (this->width >= 0) { width = this->width; } if (this->height >= 0) { height = this->height; } info.data = Mat(height, width, CV_8UC3); assert(info.data.elemSize() == 3); res = tjDecompress2(this->tj_dec, (unsigned char*) &buffer[0], length, info.data.data, width, info.data.step[0], height, TJPF_BGR, TJFLAG_ACCURATEDCT); if (res) { logger(panel, "jpeg", WARNING) << "Cannot decompress JPEG image, skipping frame" << endl; return true; } // Fill other satellite information and send frame info.valid = true; info.time = time_point< system_clock >(duration_cast< time_point< system_clock >::duration >(duration< double >(timestamp))); if (!this->first_frame_seen) { this->first_frame_seen = true; this->first_frame_time = info.time; } if (this->from_file) { info.playback_time = this->video_start_playback_time + (info.time - this->first_frame_time); } else { info.playback_time = info.time; } this->push(info); return true; }