JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize) { tjhandle handle=0; unsigned char *jpegBuf=NULL; int width=0, height=0, jpegSubsamp=-1; gethandle(); if((*env)->GetArrayLength(env, src)<jpegSize) _throw("Source buffer is not large enough"); bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); if(tjDecompressHeader2(handle, jpegBuf, (unsigned long)jpegSize, &width, &height, &jpegSubsamp)==-1) { (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); _throw(tjGetErrorStr()); } (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL; bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); (*env)->SetIntField(env, obj, _fid, jpegSubsamp); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I")); (*env)->SetIntField(env, obj, _fid, width); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I")); (*env)->SetIntField(env, obj, _fid, height); bailout: return; }
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; }
DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle h, unsigned char *srcbuf, unsigned long size, int *width, int *height) { int jpegsub; return tjDecompressHeader2(h, srcbuf, size, width, height, &jpegsub); }
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; }
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); }
bool ofxTurboJpeg::load(const ofBuffer& buf, ofPixels &pix) { int w, h; int subsamp; int ok = tjDecompressHeader2(handleDecompress, (unsigned char*)buf.getData(), buf.size(), &w, &h, &subsamp); if (ok != 0) { printf("Error in tjDecompressHeader2():\n%s\n", tjGetErrorStr()); return false; } pix.allocate(w, h, 3); tjDecompress(handleDecompress, (unsigned char*)buf.getData(), buf.size(), pix.getData(), w, 0, h, 3, 0); return true; }
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 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; }
/* 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"; } }
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; }
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; }
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; }
static const char * VS_CC check_jpeg(img_hnd_t *ih, int n, FILE *fp, vs_args_t *va) { struct stat st; #ifdef _WIN32 wchar_t tmp[FILENAME_MAX * 2]; MultiByteToWideChar(CP_UTF8, 0, ih->src[n].name, -1, tmp, FILENAME_MAX * 2); if (wstat(tmp, &st)) { #else if (stat(ih->src[n].name, &st)) { #endif return "source file does not exist"; } ih->src[n].image_size = st.st_size; if (ih->src_buff_size < st.st_size) { ih->src_buff_size = st.st_size; free(ih->src_buff); ih->src_buff = malloc(ih->src_buff_size); if (!ih->src_buff) { return "failed to allocate read buffer"; } } unsigned long read = fread(ih->src_buff, 1, st.st_size, fp); fclose(fp); if (read < st.st_size) { return "failed to read jpeg file"; } int subsample, width, height; tjhandle handle = (tjhandle)ih->tjhandle; if (tjDecompressHeader2(handle, ih->src_buff, read, &width, &height, &subsample) != 0) { return tjGetErrorStr(); } if (subsample == TJSAMP_420 || subsample == TJSAMP_422) { width += width & 1; } if (subsample == TJSAMP_420 || subsample == TJSAMP_440) { height += height & 1; } ih->src[n].width = width; ih->src[n].height = height; VSPresetFormat pf = tjsamp_to_vspresetformat(subsample); ih->src[n].format = va->vsapi->getFormatPreset(pf, va->core); uint32_t row_size = tjBufSizeYUV(width, height, subsample) / height; if (row_size > va->max_row_size) { va->max_row_size = row_size; } ih->src[n].read = read_jpeg; return NULL; } const func_check_src check_src_jpeg = check_jpeg;
/* * 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); }