Ejemplo n.º 1
0
void
jpeg_decompress(unsigned char *dst, unsigned char *src, int size, int *w, int *h) {
  struct jpeg_decompress_struct cinfo;
  //struct jpeg_error_mgr jerr;
  struct my_error_mgr mderr;
  int line_size,y;
  unsigned char *dstcur;

  //cinfo.err = jpeg_std_error(&jerr);
  cinfo.err = jpeg_std_error(&mderr.pub);
  mderr.pub.error_exit = my_error_exit;
  if(setjmp(mderr.setjmp_buffer)){
	  jpeg_destroy_decompress(&cinfo);
	  fprintf(stderr, "sonething very bad has happened\n");
	  return;
  }
  jpeg_create_decompress(&cinfo);
  jpeg_memory_src(&cinfo, src, size);
  jpeg_read_header(&cinfo, TRUE);
  jpeg_start_decompress(&cinfo);

  *w = cinfo.output_width;
  *h = cinfo.output_height;
  line_size = cinfo.output_width*cinfo.output_components;

  dstcur = dst;
  for (y = 0; y < cinfo.output_height ; y++) {
    jpeg_read_scanlines(&cinfo,(JSAMPARRAY) &dstcur,1);
    dstcur += line_size;
  }

  jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);
}
Ejemplo n.º 2
0
int jpeg_decode( unsigned char * mem_src, int size, unsigned char * mem_dst,
	int width, int height )
{
	if(!dataIsValidJPEG(mem_src,size))cout<<"JPEG file has some error"<<endl;
	struct	jpeg_decompress_struct	cinfo;
	struct	jpeg_error_mgr	jerr;

	cinfo.err = jpeg_std_error( &jerr );
	jpeg_create_decompress( &cinfo );

	jpeg_memory_src(&cinfo, mem_src, sizeof(char)*size);

	//jpeg_stdio_src( &cinfo, infile );

	int	row_stride;
	JSAMPARRAY	row_buffer;

	jpeg_read_header( &cinfo, TRUE );

	jpeg_start_decompress( &cinfo );

	if(cinfo.output_components == 1)
		cinfo.out_color_space = JCS_GRAYSCALE;
	else
		cinfo.out_color_space = JCS_EXT_BGR;

	//cout<<"channel, space "<<cinfo.output_components<<","<<cinfo.out_color_space<<endl;


	row_stride = cinfo.output_width * cinfo.output_components;
	row_buffer = ( *cinfo.mem->alloc_sarray )
		(( j_common_ptr ) &cinfo, JPOOL_IMAGE, row_stride, 1 );

	width = cinfo.output_width;
	height = cinfo.output_height;
	//image.resize( width * height * 3 );
	
	uchar* dst = mem_dst;
	int step =  width * cinfo.out_color_components;
	while ( cinfo.output_scanline < cinfo.output_height )
	{
		//cout<<cinfo.output_scanline<<endl;
		jpeg_read_scanlines( &cinfo, row_buffer, 1 );
		unsigned char	*src=row_buffer[ 0 ];

		memcpy(dst,src,sizeof(char)*width * cinfo.out_color_components);
		dst+=step;
	}
	// cout<<"finish"<<endl;
	jpeg_finish_decompress( &cinfo );
	//cout<<"destroy"<<endl;
	jpeg_destroy_decompress( &cinfo );

	return 0;
}
Ejemplo n.º 3
0
void getHeader(unsigned char * mem_src, int size, int& width, int& height, int& channels)
{
	if(!dataIsValidJPEG(mem_src,size))cout<<"JPEG file has some error"<<endl;
	
	struct	jpeg_decompress_struct	cinfo;
	struct	jpeg_error_mgr	jerr;

	cinfo.err = jpeg_std_error( &jerr );
	jpeg_create_decompress( &cinfo );
	jpeg_memory_src(&cinfo, mem_src, sizeof(char)*size);
	jpeg_read_header( &cinfo, FALSE );
	jpeg_start_decompress( &cinfo );
	

	width = cinfo.output_width;
	height = cinfo.output_height;
	channels = cinfo.output_components;
}
Ejemplo n.º 4
0
	bool ImageCodecJpg::getDimension(xs::Stream* input,uint& width,uint& height,uint& depth)
	{
		struct jpeg_decompress_struct   cinfo;
		struct jpeg_error_mgr           jerr;
		int                           loc = 0;

		// We have to set up the error handler, in case initialization fails.
		cinfo.err = jpeg_std_error(&jerr);

		// Initialize the JPEG decompression object.
		jpeg_create_decompress(&cinfo);

		// Specify data source (eg, a file, for us, memory)
		uint fileLength = input->getLength();

		SharedPtr<uchar>safeBuffer(new uchar[fileLength]);
		uchar *pMem = safeBuffer.getPointer();

		input->read(pMem,fileLength);
		jpeg_memory_src(&cinfo,pMem,fileLength);

		// Read the parameters with jpeg_read_header()
		jpeg_read_header(&cinfo,TRUE);

		// Start decompressor
		jpeg_start_decompress(&cinfo);

		// Get and set the values of interest to this object
		// Prepare the pointer object for the pixel data
		width			= cinfo.output_width;
		height			= cinfo.output_height;
		depth			= 1;

		// Release JPEG decompression object
		jpeg_destroy_decompress(&cinfo);

		return true;
	}
Ejemplo n.º 5
0
image_s *
image_new_from_jpeg(const char * path, int is_file, const char * buf, int size, int scale, int rotate)
{
	image_s *vimage;
	FILE  *file = NULL;
	struct jpeg_decompress_struct cinfo;
	unsigned char *line[16], *ptr;
	int x, y, i, w, h, ofs;
	int maxbuf;
	struct jpeg_error_mgr pub;

	cinfo.err = jpeg_std_error(&pub);
	pub.error_exit = libjpeg_error_handler;
	jpeg_create_decompress(&cinfo);
	if( is_file )
	{
		if( (file = fopen(path, "r")) == NULL )
		{
			return NULL;
		}
		jpeg_stdio_src(&cinfo, file);
	}
	else
	{
		jpeg_memory_src(&cinfo, (const unsigned char *)buf, size);
	}
	if( setjmp(setjmp_buffer) )
	{
		jpeg_destroy_decompress(&cinfo);
		if( is_file && file )
			fclose(file);
		return NULL;
	}
	jpeg_read_header(&cinfo, TRUE);
	cinfo.scale_denom = scale;
	cinfo.do_fancy_upsampling = FALSE;
	cinfo.do_block_smoothing = FALSE;
	jpeg_start_decompress(&cinfo);
	w = cinfo.output_width;
	h = cinfo.output_height;
	vimage = (rotate & (ROTATE_90|ROTATE_270)) ? image_new(h, w) : image_new(w, h);
	if(!vimage)
	{
		jpeg_destroy_decompress(&cinfo);
		if( is_file )
			fclose(file);
		return NULL;
	}

	if( setjmp(setjmp_buffer) )
	{
		jpeg_destroy_decompress(&cinfo);
		if( is_file && file )
			fclose(file);
		if( vimage )
		{
			free(vimage->buf);
			free(vimage);
		}
		return NULL;
	}

	if(cinfo.rec_outbuf_height > 16)
	{
		DPRINTF(E_WARN, L_METADATA, "ERROR image_from_jpeg : (image_from_jpeg.c) JPEG uses line buffers > 16. Cannot load.\n");
		jpeg_destroy_decompress(&cinfo);
		image_free(vimage);
		if( is_file )
			fclose(file);
		return NULL;
	}
	maxbuf = vimage->width * vimage->height;
	if(cinfo.output_components == 3)
	{
		int rx, ry;
		ofs = 0;
		if((ptr = malloc(w * 3 * cinfo.rec_outbuf_height + 16)) == NULL)
		{
			DPRINTF(E_WARN, L_METADATA, "malloc failed\n");
			jpeg_destroy_decompress(&cinfo);
			image_free(vimage);
			if( is_file )
				fclose(file);
			return NULL;
		}

		for(y = 0; y < h; y += cinfo.rec_outbuf_height)
		{
			ry = (rotate & (ROTATE_90|ROTATE_180)) ? (y - h + 1) * -1 : y;
			for(i = 0; i < cinfo.rec_outbuf_height; i++)
			{
				line[i] = ptr + (w * 3 * i);
			}
			jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
			for(x = 0; x < w * cinfo.rec_outbuf_height; x++)
			{
				rx = (rotate & (ROTATE_180|ROTATE_270)) ? (x - w + 1) * -1 : x;
				ofs = (rotate & (ROTATE_90|ROTATE_270)) ? ry + (rx * h) : rx + (ry * w);
				if( ofs < maxbuf )
					vimage->buf[ofs] = COL(ptr[x + x + x], ptr[x + x + x + 1], ptr[x + x + x + 2]);
			}
		}
		free(ptr);
	}
	else if(cinfo.output_components == 1)
	{
		ofs = 0;
		for(i = 0; i < cinfo.rec_outbuf_height; i++)
		{
			if((line[i] = malloc(w)) == NULL)
			{
				int t = 0;

				for(t = 0; t < i; t++) free(line[t]);
				jpeg_destroy_decompress(&cinfo);
				image_free(vimage);
				if( is_file )
					fclose(file);
				return NULL;
			}
		}
		for(y = 0; y < h; y += cinfo.rec_outbuf_height)
		{
			jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
			for(i = 0; i < cinfo.rec_outbuf_height; i++)
			{
				for(x = 0; x < w; x++)
				{
					vimage->buf[ofs++] = COL(line[i][x], line[i][x], line[i][x]);
				}
			}
		}
		for(i = 0; i < cinfo.rec_outbuf_height; i++)
		{
			 free(line[i]);
		}
	}
	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	if( is_file )
		fclose(file);

	return vimage;
}
UInt64 JPGImageFileType::restoreData(      Image  *OSG_JPG_ARG(pImage ), 
                                     const UChar8 *OSG_JPG_ARG(buffer ),
                                           Int32   OSG_JPG_ARG(memSize))
{
#ifdef OSG_WITH_JPG
    UInt64 retCode = 0;

    struct local_error_mgr
    {
        struct jpeg_error_mgr   pub;
        jmp_buf                 setjmp_buffer;
    };

    unsigned char                  *destData;
    Image::PixelFormat              pixelFormat = Image::OSG_INVALID_PF;

    unsigned long                    imageSize;
    typedef struct local_error_mgr  *local_error_ptr;
    struct local_error_mgr          jerr;
    struct jpeg_decompress_struct   cinfo;
    JSAMPARRAY                      imagebuffer;

    int                             row_stride;

    cinfo.err = jpeg_std_error(&jerr.pub);

    if(setjmp(jerr.setjmp_buffer))
    {
        jpeg_destroy_decompress(&cinfo);

        return 0;
    }

    jpeg_create_decompress(&cinfo);
    jpeg_memory_src(&cinfo, buffer, memSize);
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);

    switch(cinfo.output_components)
    {
        case 1:
            pixelFormat = Image::OSG_L_PF;
            break;
        case 2:
            pixelFormat = Image::OSG_LA_PF;
            break;
        case 3:
            pixelFormat = Image::OSG_RGB_PF;
            break;
        case 4:
            pixelFormat = Image::OSG_RGBA_PF;
            break;
    };

    if(pImage->set(pixelFormat, cinfo.output_width, cinfo.output_height))
    {
        imageSize = pImage->getSize();
        destData = pImage->editData() + imageSize;
        row_stride = cinfo.output_width * cinfo.output_components;

        imagebuffer = (*cinfo.mem->alloc_sarray) (j_common_ptr(&cinfo), 
                                                  JPOOL_IMAGE, 
                                                  row_stride, 
                                                  1);

        while(cinfo.output_scanline < cinfo.output_height)
        {
            destData -= row_stride;
            jpeg_read_scanlines(&cinfo, imagebuffer, 1);
            memcpy(destData, *imagebuffer, row_stride);
        }
        
        retCode = imageSize;
    }
    else
    {
        retCode = 0;
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    return retCode;
#else
    SWARNING << getMimeType() 
             << " read is not compiled into the current binary " 
             << std::endl;

    return 0;
#endif
}
Ejemplo n.º 7
0
	bool ImageCodecJpg::decode(xs::Stream* input,ImageData& data,const void  *p1,const void  *p2) const
	{
		struct jpeg_decompress_struct   cinfo;
		struct jpeg_error_mgr           jerr;
		int                           loc = 0;

		// We have to set up the error handler, in case initialization fails.
		cinfo.err = jpeg_std_error(&jerr);

		// Initialize the JPEG decompression object.
		jpeg_create_decompress(&cinfo);

		// Specify data source (eg, a file, for us, memory)
		uint fileLength = input->getLength();

		SharedPtr<uchar>safeBuffer(new uchar[fileLength]);
		uchar *pMem = safeBuffer.getPointer();

		input->read(pMem,fileLength);
		jpeg_memory_src(&cinfo,pMem,fileLength);

		// Read the parameters with jpeg_read_header()
		jpeg_read_header(&cinfo,TRUE);

		// Set parameters for decompression
		// (We do nothing here since the defaults are fine)

		// Start decompressor
		jpeg_start_decompress(&cinfo);

		// JSAMPLEs per row in output buffer
		int bpp         = cinfo.output_components;

		if(bpp != 1 && bpp != 3 && bpp != 4)
		{
			Error("JPG Channels must be 1,3,4;");
			return false;
		}
		int row_stride  = cinfo.output_width * bpp;

		// Get and set the values of interest to this object
		// Prepare the pointer object for the pixel data
		data.width			= cinfo.output_width;
		data.height			= cinfo.output_height;
		data.depth			= 1;
		data.num_mipmaps	= 1;
		//渲染引擎是大头的,因此PF_R8G8B8不被D3D9支持,所以将解码后的格式改为PF_B8G8R8
		//data.format			= PF_R8G8B8;
		data.format			= PF_B8G8R8;
		data.flags			= 0;
		data.size			=	data.width * data.height * 3;
		data.pData			=	new uchar[data.size];

		// Make a one-row-high sample array that will go away when done with image
		JSAMPARRAY temp = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,row_stride,1);

		// Read data on a scanline by scanline basis
		while(cinfo.output_scanline < cinfo.output_height)
		{
			// We may need to adjust the output based on the
			// number of channels it has.
			switch (bpp) 
			{
			case 1:
				// Grayscale; decompress to temp.
				jpeg_read_scanlines(&cinfo, temp, 1);
				// Expand to three channels
				{
					uchar* scan     = &(data.pData[(loc/1) * 3]);
					uchar* endScan  = scan + (data.width * 3);
					uchar* t        = *temp;

					while (scan < endScan)
					{
						uchar value = t[0];

						// Spread the value 3x.
						scan[0] = value;
						scan[1] = value;
						scan[2] = value;

						scan    += 3;
						t       += 1;
					}
				}
				break;
			case 3:
				// Read directly into the array
				{

#if 0
					// Need one extra level of indirection.
					uchar*     scan = data.pData + loc;
					JSAMPARRAY ptr  = &scan;
					jpeg_read_scanlines(&cinfo, ptr, 1);

#else //将格式转化为 PF_B8G8R8 
					// Need one extra level of indirection.
					uchar*     scan = data.pData + (loc/3)*3;
					JSAMPARRAY ptr  = &scan;
					jpeg_read_scanlines(&cinfo, ptr, 1);
					uchar *		endScan = scan + data.width * 3;
					uchar swap = 0;
					while( scan < endScan)
					{
						swap = scan[0];
						scan[0] = scan[2];
						scan[2] = swap;
						scan += 3;
					}
#endif 
				}
				break;
			case 4:
				// RGBA; decompress to temp.
				jpeg_read_scanlines(&cinfo, temp, 1);
				// Drop the 3rd channel
				{
#if 0
					uchar* scan     = &(data.pData[loc * 3]);//这个指针有错误
					uchar* endScan  = scan + data.width * 3;
					uchar* t        = *temp;

					while (scan < endScan)
					{
						scan[0] = t[0];
						scan[1] = t[1];
						scan[2] = t[2];
						scan    += 3;
						t       += 4;
					}
#else	//将格式转化为 PF_B8G8R8 
					uchar* scan     = &( data.pData[(loc/4)*3] );
					uchar* endScan  = scan + data.width * 3;
					uchar* t        = *temp;
					while (scan < endScan)
					{
						scan[0] = t[2];
						scan[1] = t[1];
						scan[2] = t[0];
						scan    += 3;
						t       += 4;
					}
#endif
				}
				break;
			}

			loc += row_stride;
		}

		// Finish decompression
		jpeg_finish_decompress(&cinfo);

		// Release JPEG decompression object
		jpeg_destroy_decompress(&cinfo);

		return true;
	}
Ejemplo n.º 8
0
static mrb_value
mrb_jpeg_decompress_common(mrb_state *mrb, mrb_value self, enum decompress_type dtype)
{
  struct jpeg_decompress_struct dinfo;
  struct jpeg_error_mgr jpeg_error;
  long scanline_size;
  void *jpeg_data;
  int row = 0;
  struct RClass* module_jpeg;
  struct RClass* class_jpeg_image;
  mrb_value ivar;

  mrb_value arg_config_hash = mrb_nil_value();
  mrb_value arg_data = mrb_nil_value();

  int argc = mrb_get_args(mrb, "S|H", &arg_data, &arg_config_hash);
  if (mrb_nil_p(arg_data) || mrb_type(arg_data) != MRB_TT_STRING) 
  {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid argument");
  }
  if(argc > 1 && mrb_type(arg_config_hash) != MRB_TT_HASH)
  {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid argument");
  }
  
  dinfo.client_data = mrb;

  dinfo.err = jpeg_std_error(&jpeg_error);
  dinfo.err->error_exit = jpeg_error_func;

  jpeg_create_decompress(&dinfo);

  if(dtype == FILE_SRC)
  {
    FILE *fp = fopen(RSTRING_PTR(arg_data), "r");
    if(fp == NULL)
    {
      jpeg_destroy_decompress(&dinfo);
      mrb_raise(mrb, E_RUNTIME_ERROR, "Could not open input file.");
    }
    jpeg_stdio_src(&dinfo, fp);
  }
  else
  {
    jpeg_memory_src(&dinfo, (const JOCTET *)RSTRING_PTR(arg_data), RSTRING_LEN(arg_data));
  }

  jpeg_read_header(&dinfo, 1); 

  if(!mrb_obj_equal(mrb, arg_config_hash, mrb_nil_value()) && HASH_TRUE(mrb, arg_config_hash, "force_grayscale"))
  {
    dinfo.output_components = 1;
  }
  else
  {
    if (dinfo.out_color_space == JCS_GRAYSCALE) 
    {
      dinfo.output_components = 1;
    }
    else 
    {
      dinfo.output_components = 3;
      dinfo.out_color_space = JCS_RGB;
    }
  }

  jpeg_start_decompress(&dinfo);

  scanline_size = dinfo.image_width * dinfo.output_components;
  jpeg_data = malloc(scanline_size * dinfo.image_height);

  for(row = 0; row < dinfo.image_height; row++)
  {
    JSAMPROW jpeg_row = (JSAMPROW)(jpeg_data + (scanline_size * row));
    jpeg_read_scanlines(&dinfo, &jpeg_row, 1);
  }

  module_jpeg = mrb_module_get(mrb, "JPEG");
  class_jpeg_image = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(module_jpeg), mrb_intern_lit(mrb, "JPEGImage")));
  ivar = mrb_class_new_instance(mrb, 0, NULL, class_jpeg_image);
  mrb_iv_set(mrb, ivar, mrb_intern_lit(mrb, "data"), mrb_str_new(mrb, jpeg_data, scanline_size * dinfo.image_height));
  mrb_iv_set(mrb, ivar, mrb_intern_lit(mrb, "width"), mrb_fixnum_value(dinfo.image_width));
  mrb_iv_set(mrb, ivar, mrb_intern_lit(mrb, "height"), mrb_fixnum_value(dinfo.image_height));

  jpeg_finish_decompress(&dinfo);
  jpeg_destroy_decompress(&dinfo);

  return ivar;
}
Ejemplo n.º 9
0
// Load JPG from memory
unsigned char* LoadJPGWithAlphaFromMemory(const unsigned char* begin, int len, int* width, int* height)
{
	jpeg_decompress_struct cinfo;
	jpeg_error_mgr jerr;
	
	cinfo.err=jpeg_std_error(&jerr);
	jerr.error_exit=error_jpeg_exit;

	#ifdef ENABLE_JPG_EXCEPTION
	try
	#endif
	{
		// Init decompressor
		jpeg_create_decompress(&cinfo);
		jpeg_memory_src(&cinfo, (const char*)begin, (const char*)(begin+len));
		jpeg_read_header(&cinfo,TRUE);
		jpeg_start_decompress(&cinfo);

		int wi=cinfo.image_width;
		int he=cinfo.image_height;

		int bytes_per_line=cinfo.output_width*cinfo.output_components;
		int bytes_per_line4=cinfo.output_width*4;

		unsigned char* data=new unsigned char[bytes_per_line4*he];
		unsigned char* data_temp=new unsigned char[bytes_per_line];

		//построчно читаем данные
		unsigned char* line = data;
		while (cinfo.output_scanline < cinfo.output_height)
		{
			jpeg_read_scanlines(&cinfo, &data_temp, 1);

			int temp_index=0;
			for (unsigned int i=0;i<cinfo.output_width;i++)
			{
				*line=data_temp[temp_index];
				temp_index++;
				line++;
				*line=data_temp[temp_index];
				temp_index++;
				line++;
				*line=data_temp[temp_index];
				temp_index++;
				line++;
				*line=255;
				line++;
			}

		}
		delete []data_temp;

		//подчищаем
		jpeg_finish_decompress(&cinfo);
		jpeg_destroy_decompress(&cinfo);

		*width=wi;
		*height=he;

		return data;
	}
	#ifdef ENABLE_JPG_EXCEPTION
	catch (...)
	{
		jpeg_destroy((j_common_ptr)&cinfo);
		return NULL;
	}
	#endif
}
Ejemplo n.º 10
0
// convert in memory jpeg to bmp
uint08 *jpeg2bmp(uint08 *jpeg, uint32 jpegSize, uint32 *bmpSize, uint32 *bmpWidth, uint32 *bmpHeight)
{
    jpeg_decompress_struct cinfo;
    jpeg_error_mgr         jerr;

    uint08 *buffer = 0, *bufcur = 0;

    uint32 row_stride = 0, y;

    cinfo.err = jpeg_std_error(&jerr);

    // initialize jpeg decompression object
    jpeg_create_decompress(&cinfo);

    // specify data source
    //jpeg_stdio_src(&cinfo, infile);
    jpeg_memory_src(&cinfo, jpeg, jpegSize);

    // read jpeg header
    jpeg_read_header(&cinfo, TRUE);

    // begin decompression
    jpeg_start_decompress(&cinfo);

    // update row_stride
    row_stride = cinfo.output_width * cinfo.output_components;

    // save these for caller
    *bmpWidth = cinfo.output_width;
    *bmpHeight = cinfo.output_height;

    // calculate bitmap size
    *bmpSize = row_stride*cinfo.output_height;

    // allocate bitmap data
    buffer = (uint08*)malloc(*bmpSize);

    bufcur = buffer;
    for(y=0;y<cinfo.output_height;y++)
    {
        jpeg_read_scanlines(&cinfo, (JSAMPARRAY)&bufcur, 1);
        bufcur += row_stride;
    }

    // re-order color data
    {
        uint32 v=0;

        for(v=0;v<cinfo.output_width*cinfo.output_height;v++)
        {
            uint08 r = buffer[v*3+2];
            uint08 g = buffer[v*3+1];
            uint08 b = buffer[v*3+0];

            buffer[v*3+2] = b;
            buffer[v*3+1] = g;
            buffer[v*3+0] = r;
        }
    }

    jpeg_finish_decompress(&cinfo);

    free(cinfo.src);

    jpeg_destroy_decompress(&cinfo);

    *bmpSize = row_stride*cinfo.output_height;

    return (uint08*)buffer;
}
Ejemplo n.º 11
0
static void jpeg_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
  jpeg_decoder_t *this = (jpeg_decoder_t *) this_gen;

  if (!this->video_open) {
    lprintf("opening video\n");
    (this->stream->video_out->open) (this->stream->video_out, this->stream);
    this->video_open = 1;
  }

  xine_buffer_copyin(this->image, this->index, buf->mem, buf->size);
  this->index += buf->size;

  if (buf->decoder_flags & BUF_FLAG_FRAME_END && this->index > 0) {
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPARRAY buffer;

    int         i, linesize;
    int         width, height;
    vo_frame_t *img;
    int         max_width, max_height;
    uint8_t    *slice_start[1] = {NULL};
    int         slice_line = 0;

    /* query max. image size vo can handle */
    max_width = this->stream->video_out->get_property( this->stream->video_out,
                                                       VO_PROP_MAX_VIDEO_WIDTH);
    max_height = this->stream->video_out->get_property( this->stream->video_out,
                                                        VO_PROP_MAX_VIDEO_HEIGHT);

    /* init and parse header */

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    jpeg_memory_src(&cinfo, this->image, this->index);
    jpeg_read_header(&cinfo, TRUE);

    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH,  cinfo.image_width);
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, cinfo.image_height);

    lprintf("header parsed\n");

    /* set decoding parameters */

    cinfo.out_color_space = JCS_YCbCr;

    /* request scaling when image is too large for vo */
    if (this->cls->enable_downscaling) {
      cinfo.output_width  = cinfo.image_width;
      cinfo.output_height = cinfo.image_height;
      cinfo.scale_num   = 1;
      cinfo.scale_denom = 1;
      while ((max_width  > 0 && cinfo.output_width  > max_width) ||
             (max_height > 0 && cinfo.output_height > max_height)) {
        cinfo.scale_denom   <<= 1;
        cinfo.output_width  >>= 1;
        cinfo.output_height >>= 1;
      }
      if (cinfo.scale_denom > 1) {
        xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
                LOG_MODULE ": downscaling image by 1:%d to %dx%d\n",
                cinfo.scale_denom, cinfo.output_width, cinfo.output_height);
      }
    }

    /* start decompress */

    jpeg_start_decompress(&cinfo);

    width = cinfo.output_width;
    height = cinfo.output_height;

    /* crop when image is too large for vo */
    if (max_width > 0 && cinfo.output_width > max_width)
      width = max_width;
    if (max_height > 0 && cinfo.output_height > max_height)
      height = max_height;

    img = this->stream->video_out->get_frame (this->stream->video_out,
                                              width, height,
                                              (double)width/(double)height,
					      XINE_IMGFMT_YUY2,
    					      VO_BOTH_FIELDS);

    linesize = cinfo.output_width * cinfo.output_components;
    buffer = (cinfo.mem->alloc_sarray)((void*)&cinfo, JPOOL_IMAGE, linesize, 1);
    if (img->proc_slice && !(img->height & 0xf)) {
      slice_start[0] = img->base[0];
    }

    /* cut to frame width */
    if (cinfo.output_width > img->width) {
      lprintf("cut right border %d pixels\n", cinfo.output_width - img->width);
      linesize = img->width * 3;
    }

    /* YUV444->YUV422 simple */
    while (cinfo.output_scanline < cinfo.output_height) {
      uint8_t *dst = img->base[0] + img->pitches[0] * cinfo.output_scanline;

      jpeg_read_scanlines(&cinfo, buffer, 1);

      /* cut to frame height */
      if (cinfo.output_scanline > img->height) {
        lprintf("cut bottom scanline %d\n", cinfo.output_scanline - 1);
        continue;
      }

      for (i = 0; i < linesize; i += 3) {
        *dst++ = buffer[0][i];
        if (i & 1) {
          *dst++ = buffer[0][i + 2];
        } else {
          *dst++ = buffer[0][i + 1];
        }
      }

      if (slice_start[0]) {
        slice_line++;
        if (slice_line == 16) {
          img->proc_slice(img, slice_start);
          slice_start[0] += 16 * img->pitches[0];
          slice_line = 0;
        }
      }
    }

    /* final slice */
    if (slice_start[0] && slice_line) {
      img->proc_slice(img, slice_start);
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    img->pts       = buf->pts;
    img->duration  = 3600;
    img->bad_frame = 0;

    _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration);

    img->draw(img, this->stream);
    img->free(img);

    this->index = 0;
  }
Ejemplo n.º 12
0
bool loadJPEGScaled(QImage& image, const QString& path, int maximumSize)
{
    FileReadLocker lock(path);

    if (!isJpegImage(path))
    {
        return false;
    }

    FILE* const inputFile = fopen(QFile::encodeName(path).constData(), "rb");

    if (!inputFile)
    {
        return false;
    }

    struct jpeg_decompress_struct   cinfo;

    struct jpegutils_jpeg_error_mgr jerr;

    // JPEG error handling - thanks to Marcus Meissner
    cinfo.err                 = jpeg_std_error(&jerr);
    cinfo.err->error_exit     = jpegutils_jpeg_error_exit;
    cinfo.err->emit_message   = jpegutils_jpeg_emit_message;
    cinfo.err->output_message = jpegutils_jpeg_output_message;

    if (setjmp(jerr.setjmp_buffer))
    {
        jpeg_destroy_decompress(&cinfo);
        fclose(inputFile);
        return false;
    }

    jpeg_create_decompress(&cinfo);

#ifdef Q_OS_WIN

    QFile inFile(path);
    QByteArray buffer;

    if (inFile.open(QIODevice::ReadOnly))
    {
        buffer = inFile.readAll();
        inFile.close();
    }

    jpeg_memory_src(&cinfo, (JOCTET*)buffer.data(), buffer.size());

#else  // Q_OS_WIN

    jpeg_stdio_src(&cinfo, inputFile);

#endif // Q_OS_WIN

    jpeg_read_header(&cinfo, true);

    int imgSize = qMax(cinfo.image_width, cinfo.image_height);

    // libjpeg supports 1/1, 1/2, 1/4, 1/8
    int scale=1;

    while(maximumSize*scale*2 <= imgSize)
    {
        scale *= 2;
    }

    if (scale > 8)
    {
        scale = 8;
    }

    //cinfo.scale_num = 1;
    //cinfo.scale_denom = scale;
    cinfo.scale_denom *= scale;

    switch (cinfo.jpeg_color_space)
    {
        case JCS_UNKNOWN:
            break;
        case JCS_GRAYSCALE:
        case JCS_RGB:
        case JCS_YCbCr:
            cinfo.out_color_space = JCS_RGB;
            break;
        case JCS_CMYK:
        case JCS_YCCK:
            cinfo.out_color_space = JCS_CMYK;
            break;
        default:
            break;
    }

    jpeg_start_decompress(&cinfo);

    QImage img;

    // We only take RGB with 1 or 3 components, or CMYK with 4 components
    if (!(
            (cinfo.out_color_space == JCS_RGB  && (cinfo.output_components == 3 || cinfo.output_components == 1)) ||
            (cinfo.out_color_space == JCS_CMYK &&  cinfo.output_components == 4)
        ))
    {
        jpeg_destroy_decompress(&cinfo);
        fclose(inputFile);
        return false;
    }

    switch (cinfo.output_components)
    {
        case 3:
        case 4:
            img = QImage(cinfo.output_width, cinfo.output_height, QImage::Format_RGB32);
            break;
        case 1: // B&W image
            img = QImage(cinfo.output_width, cinfo.output_height, QImage::Format_Indexed8);
            img.setColorCount(256);

            for (int i = 0 ; i < 256 ; ++i)
            {
                img.setColor(i, qRgb(i, i, i));
            }

            break;
    }

    uchar* const data = img.bits();
    int bpl           = img.bytesPerLine();

    while (cinfo.output_scanline < cinfo.output_height)
    {
        uchar* d = data + cinfo.output_scanline * bpl;
        jpeg_read_scanlines(&cinfo, &d, 1);
    }

    jpeg_finish_decompress(&cinfo);

    if (cinfo.output_components == 3)
    {
        // Expand 24->32 bpp.
        for (uint j=0; j<cinfo.output_height; ++j)
        {
            uchar* in       = img.scanLine(j) + cinfo.output_width * 3;
            QRgb* const out = reinterpret_cast<QRgb*>(img.scanLine(j));

            for (uint i = cinfo.output_width; --i; )
            {
                in     -= 3;
                out[i] = qRgb(in[0], in[1], in[2]);
            }
        }
    }
    else if (cinfo.out_color_space == JCS_CMYK)
    {
        for (uint j = 0; j < cinfo.output_height; ++j)
        {
            uchar* in       = img.scanLine(j) + cinfo.output_width * 4;
            QRgb* const out = reinterpret_cast<QRgb*>(img.scanLine(j));

            for (uint i = cinfo.output_width; --i; )
            {
                in     -= 4;
                int k  = in[3];
                out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255);
            }
        }
    }

    if (cinfo.density_unit == 1)
    {
        img.setDotsPerMeterX(int(100. * cinfo.X_density / 2.54));
        img.setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54));
    }
    else if (cinfo.density_unit == 2)
    {
        img.setDotsPerMeterX(int(100. * cinfo.X_density));
        img.setDotsPerMeterY(int(100. * cinfo.Y_density));
    }

    //int newMax = qMax(cinfo.output_width, cinfo.output_height);
    //int newx = maximumSize*cinfo.output_width / newMax;
    //int newy = maximumSize*cinfo.output_height / newMax;

    jpeg_destroy_decompress(&cinfo);
    fclose(inputFile);

    image = img;

    return true;
}
Ejemplo n.º 13
0
Image ImageJpgFile (uint8_t * buf, uint32_t size)
{
   ImageFile *Image;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr jerr;
  int row_stride;    /* physical row width in output buffer */
  JSAMPARRAY buffer;
  int bufp;
  int i;
//  RGBcolor *out;

  /* ==== Step 1: allocate and initialize JPEG decompression object */
  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr.pub);
  
  jerr.pub.error_exit = my_error_exit;

  if (setjmp(jerr.setjmp_buffer))
  {
	  jpeg_destroy_decompress(&cinfo);
	  return NULL;
  }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* ==== Step 2: specify data source (memory buffer, in this case) */
  jpeg_memory_src (&cinfo, (char *)buf, size);

  /* ==== Step 3: read file parameters with jpeg_read_header() */
  (void) jpeg_read_header(&cinfo, TRUE);

  /* ==== Step 4: set parameters for decompression */
  // We want max quality, doesnt matter too much it can be a bit slow

  // We almost always want RGB output (no grayscale, yuv etc)
  if (cinfo.jpeg_color_space != JCS_GRAYSCALE)
    cinfo.out_color_space = JCS_RGB;

  // Recalculate output image dimensions
  jpeg_calc_output_dimensions (&cinfo);

  /* ==== Step 5: Start decompressor */

  (void) jpeg_start_decompress (&cinfo);
  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */
  Image = MakeImageFile(cinfo.output_width, cinfo.output_height);

  /* JSAMPLEs per row in output buffer */
  row_stride = cinfo.output_width * cinfo.output_components;
  /* Make a one-row-high sample array that will go away when done with image */
   buffer = (*cinfo.mem->alloc_sarray)
    ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, cinfo.output_height);

   // read into the buffer upside down...
   for( i = 0; i < Image->height; i++ )
	{
		if( Image->flags & IF_FLAG_INVERTED )
   	   buffer[i] = (JSAMPROW)(Image->image + 
                  ( ( (Image->height - i) - 1 ) * Image->width ));
		else
	      buffer[i] = (JSAMPROW)(Image->image + (  i * Image->width ));
	}

  /* ==== Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  bufp = 0;
   while (cinfo.output_scanline < cinfo.output_height)
      jpeg_read_scanlines( &cinfo, buffer + cinfo.output_scanline, cinfo.image_height );


  /* blah! we're in 32 bit color space - and this reads 
   * into 24 bit space - WHY oh WHY is that... ahh well
   * we need to update this */
   for( i = 0; i < Image->height; i++ )
   {
      int j;
      char *row;
      row = (char*)buffer[i];
      for( j = Image->width; j > 0; j-- )
      {
			row[j * 4 - 1] = (uint8_t)0xff;
			if( bGLColorMode )
			{
				row[j * 4 - 2] = row[j*3-1];
				row[j * 4 - 3] = row[j*3-2];
				row[j * 4 - 4] = row[j*3-3];
			}
			else
			{
				row[j * 4 - 2] = row[j*3-3];
				row[j * 4 - 3] = row[j*3-2];
				row[j * 4 - 4] = row[j*3-1];
			}
      }
   }
  /* ==== Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the buffer data source.
   */

  /* ==== Step 8: Release JPEG decompression object */
  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress(&cinfo);


  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
   */
  /* And we're done! */
  return Image;
}
Ejemplo n.º 14
0
void processimage (const void *p, int l)
{

	struct jpeg_decompress_struct mycinfo;
	struct my_error_mgr myjerr;
	JSAMPARRAY jpegbuffer=NULL;
	int row_stride;

	mycinfo.err = jpeg_std_error(&myjerr.pub);
	myjerr.pub.error_exit = my_error_exit;
	if (setjmp(myjerr.setjmp_buffer)) {
		jpeg_destroy_decompress(&mycinfo);
		return ;/*exit(0);*/
	}
	jpeg_create_decompress(&mycinfo);

	jpeg_memory_src(&mycinfo, p, l) ;

	((memory_source_mgr *)mycinfo.src)->pub.next_input_byte = (JOCTET*)p;
	((memory_source_mgr *)mycinfo.src)->pub.bytes_in_buffer = l;

	jpeg_read_header(&mycinfo, TRUE);

	mycinfo.out_color_space = JCS_RGB;
	mycinfo.dct_method = JDCT_IFAST;
	mycinfo.jpeg_color_space = JCS_YCbCr;

	my_jpeg_load_dht( &mycinfo, 
		my_jpeg_odml_dht, 
		mycinfo.ac_huff_tbl_ptrs, 
		mycinfo.dc_huff_tbl_ptrs ); 

	jpeg_start_decompress(&mycinfo);

	row_stride = mycinfo.image_width * mycinfo.num_components;

	if(rgb == NULL){
		IMG_WIDTH=mycinfo.image_width;
		IMG_HEIGHT=mycinfo.image_height;
		rgb = (int *)malloc(sizeof(int) * (IMG_WIDTH*IMG_HEIGHT));
	}

	if(jpegbuffer==NULL){
		jpegbuffer = (*mycinfo.mem->alloc_sarray)
			((j_common_ptr) &mycinfo, JPOOL_IMAGE, row_stride, 1);
	}

	int y = 0;
	int *outp=rgb;
	while ( mycinfo.output_scanline < mycinfo.image_height) {

		jpeg_read_scanlines(&mycinfo, jpegbuffer, 1);

		int xx;
		int x3;

		for(xx = 0, x3 = 0; xx < IMG_WIDTH && x3 < row_stride; xx++, x3 += 3)
		{
			outp[y+xx] = 0xff000000 | jpegbuffer[0][x3 + 2]<<16
				| jpegbuffer[0][x3 + 1]<<8 | jpegbuffer[0][x3 + 0];
		}

		y+=IMG_WIDTH;
	}

	jpeg_finish_decompress(&mycinfo);
	jpeg_destroy_decompress(&mycinfo);
	
}
Ejemplo n.º 15
0
void GImage::decodeJPEG(
    BinaryInput&                input) {

	struct jpeg_decompress_struct   cinfo;
	struct jpeg_error_mgr           jerr;
    int                             loc = 0;

    channels = 3;
    // We have to set up the error handler, in case initialization fails.
	cinfo.err = jpeg_std_error(&jerr);

    // Initialize the JPEG decompression object.
	jpeg_create_decompress(&cinfo);

	// Specify data source (eg, a file, for us, memory)
	jpeg_memory_src(&cinfo, const_cast<uint8*>(input.getCArray()), input.size());

	// Read the parameters with jpeg_read_header()
	jpeg_read_header(&cinfo, TRUE);

	// Set parameters for decompression
	// (We do nothing here since the defaults are fine)

	// Start decompressor
	jpeg_start_decompress(&cinfo);

	// Get and set the values of interest to this object
	this->width     = cinfo.output_width;
	this->height    = cinfo.output_height;

	// Prepare the pointer object for the pixel data
    _byte = (uint8*)System::malloc(width * height * 3);

 	// JSAMPLEs per row in output buffer
    int bpp         = cinfo.output_components;
    int row_stride  = cinfo.output_width * bpp;

	// Make a one-row-high sample array that will go away when done with image
    JSAMPARRAY temp = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

    // Read data on a scanline by scanline basis
	while (cinfo.output_scanline < cinfo.output_height) {

        // We may need to adjust the output based on the
        // number of channels it has.
        switch (bpp) {
	    case 1:
            // Grayscale; decompress to temp.
    		jpeg_read_scanlines(&cinfo, temp, 1);

            // Expand to three channels
            {
                uint8* scan     = &(_byte[loc * 3]);
                uint8* endScan  = scan + (width * 3);
                uint8* t        = *temp;

                while (scan < endScan) {
                    uint8 value = t[0];

                    // Spread the value 3x.
                    scan[0] = value;
                    scan[1] = value;
                    scan[2] = value;

                    scan    += 3;
                    t       += 1;
                }
            }
		    break;

	    case 3:
            // Read directly into the array
            {
                // Need one extra level of indirection.
                uint8*     scan = _byte + loc;
                JSAMPARRAY ptr  = &scan;
    		    jpeg_read_scanlines(&cinfo, ptr, 1);
            }
		    break;

	    case 4:
            // RGBA; decompress to temp.
    		jpeg_read_scanlines(&cinfo, temp, 1);

            // Drop the 3rd channel
            {
                uint8* scan     = &(_byte[loc * 3]);
                uint8* endScan  = scan + width * 3;
                uint8* t        = *temp;

                while (scan < endScan) {
                    scan[0] = t[0];
                    scan[1] = t[1];
                    scan[2] = t[2];
                    
                    scan    += 3;
                    t       += 4;
                }
            }
		    break;

	    default:
		    throw Error("Unexpected number6 of channels.", input.getFilename());
	    }

		loc += row_stride;
	}

	// Finish decompression
	jpeg_finish_decompress(&cinfo);

	// Release JPEG decompression object
	jpeg_destroy_decompress(&cinfo);
}
Ejemplo n.º 16
0
bool ImageJpgFile::JpegLoader::InitOk()
{
  // For now we don't support alpha-map images
  // The libjpeg docs are unclear on this subject, it seems that alpha
  // mapped images could be supported by libjpeg (it supports a random
  // number of abstract color channels) but I (A.Z.) just don't have
  // alpha-mapped JPEG images and can't test it.
  Format &= ~CS_IMGFMT_ALPHA;

  /* ==== Step 1: allocate and initialize JPEG decompression object */
  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  if (setjmp (jerr.setjmp_buffer))
  {
    char errmsg [256];
    if (cinfo.err->msg_code != JERR_NO_SOI)
    {
      cinfo.err->format_message ((jpeg_common_struct *)&cinfo, errmsg);
      Report (object_reg, CS_REPORTER_SEVERITY_WARNING,
	"%s\n", errmsg);
    }
    if (decompCreated) jpeg_destroy_decompress (&cinfo);
    decompCreated = false;
    return false;
  }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);
  decompCreated = true;

  /* ==== Step 2: specify data source (memory buffer, in this case) */
  jpeg_memory_src (&cinfo, dataSource->GetData(), (int)dataSource->GetSize());

  /* ==== Step 3: read file parameters with jpeg_read_header() */
  (void) jpeg_read_header(&cinfo, TRUE);

  bool isGrayScale = cinfo.jpeg_color_space == JCS_GRAYSCALE;
  /* ==== Step 4: set parameters for decompression */
  // We want max quality, doesnt matter too much it can be a bit slow
  if (isGrayScale)
    dataType = rdtIndexed;
  else
    dataType = rdtR8G8B8;
  // We almost always want RGB output (no grayscale, yuv etc)
  if (cinfo.jpeg_color_space != JCS_GRAYSCALE)
    cinfo.out_color_space = JCS_RGB;

  // Recalculate output image dimensions
  jpeg_calc_output_dimensions (&cinfo);

  /* ==== Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);
  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */
  Width = cinfo.output_width;
  Height = cinfo.output_height;

  if ((Format & CS_IMGFMT_MASK) == CS_IMGFMT_ANY)
    Format = (Format & ~CS_IMGFMT_MASK) |
      (isGrayScale ? CS_IMGFMT_PALETTED8 : CS_IMGFMT_TRUECOLOR);

  return true;
}