Beispiel #1
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #9
0
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;
}
Beispiel #11
0
/* 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";
    }
}
Beispiel #13
0
bool JPEGReader::process_frame() {

  // Read from stream
  double timestamp;
  uint32_t length;
  this->fin->read((char*) &timestamp, 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;

}
Beispiel #14
0
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;
}
Beispiel #16
0
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);
    
}