Esempio n. 1
1
/* put_jpeg_yv12_memory converts an input image in the YUV420P format into a jpeg image and puts
 * it in a memory buffer.
 * Inputs:
 * - input_image is the image in YV12 format.
 * - width and height are the dimensions of the image
 * Output:
 * - dest_image is a pointer to the jpeg image buffer
 * Returns buffer size of jpeg image     
 */
long put_jpeg_yv12_memory(unsigned char *dest_image,unsigned char *input_image, int width, int height,int quality){
    int i, j, jpeg_image_size;

    JSAMPROW y[16],cb[16],cr[16]; // y[2][5] = color sample of row 2 and pixel column 5; (one plane)
    JSAMPARRAY data[3]; // t[0][2][5] = color sample 0 of row 2 and column 5

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    data[0] = y;
    data[1] = cr;
    data[2] = cb;

    cinfo.err = jpeg_std_error(&jerr);  // errors get written to stderr 
    
    jpeg_create_compress(&cinfo);
    cinfo.image_width = width;
    cinfo.image_height = height/16*16;
    cinfo.input_components = 3;
    jpeg_set_defaults (&cinfo);

    jpeg_set_colorspace(&cinfo, JCS_YCbCr);

    cinfo.raw_data_in = TRUE;                  // supply downsampled data
    cinfo.comp_info[0].h_samp_factor = 2;
    cinfo.comp_info[0].v_samp_factor = 2;
    cinfo.comp_info[1].h_samp_factor = 1;
    cinfo.comp_info[1].v_samp_factor = 1;
    cinfo.comp_info[2].h_samp_factor = 1;
    cinfo.comp_info[2].v_samp_factor = 1;

    jpeg_set_quality(&cinfo, quality, TRUE);
    cinfo.dct_method = JDCT_FASTEST;

    jpeg_mem_dest(&cinfo, dest_image, cinfo.image_width*cinfo.image_height*3/2);    // data written to mem
    
    jpeg_start_compress(&cinfo, TRUE);

    for (j = 0; j < cinfo.image_height; j += 16) {
        for (i = 0; i < 16; i++) {
            y[i] = input_image + width * (i + j);
            if (i%2 == 0) {
                cb[i/2] = input_image + width * height + width / 2 * ((i + j) / 2);
                cr[i/2] = input_image + width * height + width * height / 4 + width / 2 * ((i + j) / 2);
            }
        }
		jpeg_write_raw_data(&cinfo, data, 16);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_image_size = jpeg_mem_size(&cinfo);
    jpeg_destroy_compress(&cinfo);
    
    return jpeg_image_size;
}
Esempio n. 2
0
File: main.c Progetto: Kleshni/Eph5
result save(void) {
	// Set error manager

	struct jpeg_compress_struct compressor;

	compressor.err = &error_manager;

	if (setjmp(catch)) {
		jpeg_destroy_compress(&compressor);

		return LibJPEG_error_message;
	}

	// Initialize compression structure

	unsigned long new_data_length = data_length;

	jpeg_create_compress(&compressor);
	jpeg_mem_dest(&compressor, &data_buffer, &new_data_length);
	LibEph5_write(&context, &compressor);
	jpeg_finish_compress(&compressor);

	data_length = new_data_length;

	// Clean up

	jpeg_destroy_compress(&compressor);

	return result_OK;
}
Esempio n. 3
0
// http://stackoverflow.com/a/2296662
size_t compress_rgb(uint8_t * in, uint8_t * out, int width, int height)
{
  struct jpeg_compress_struct cinfo = { 0 };
  struct jpeg_error_mgr jerr;
  JSAMPROW row_ptr[1];
  int row_stride;
  unsigned long int length = 0;
  unsigned char * output = NULL;
  
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
  jpeg_mem_dest(&cinfo, &output, &length);
  
  cinfo.image_width = width;
  cinfo.image_height = height;
  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;
  
  jpeg_set_defaults(&cinfo);
  jpeg_start_compress(&cinfo, TRUE);
  row_stride = width * 3;
  
  while (cinfo.next_scanline < cinfo.image_height) {
    row_ptr[0] = &out[cinfo.next_scanline * row_stride];
    jpeg_write_scanlines(&cinfo, row_ptr, 1);
  }
  
  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);
  
  memcpy(out, output, length);
  
  return length;
}
Esempio n. 4
0
/*
 * Compress RGB buffer in memory
 */
int RGB_2_JPEG(unsigned char *buffer, unsigned char **compressed, long unsigned int *new_len, int quality) {
	struct jpeg_compress_struct cinfo = {0};
	struct jpeg_error_mgr jerr;
	JSAMPROW row_ptr[1];
	int row_stride;

	*compressed = NULL;
	*new_len = 0;

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);
	jpeg_mem_dest(&cinfo, compressed, new_len);

	cinfo.image_width = 640;
	cinfo.image_height = 480;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, quality, TRUE);
	jpeg_start_compress(&cinfo, TRUE);
	row_stride = 640 * 3;

	while (cinfo.next_scanline < cinfo.image_height) {
		row_ptr[0] = &buffer[cinfo.next_scanline * row_stride];
		jpeg_write_scanlines(&cinfo, row_ptr, 1);
	}

	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);

	return 1;
}
/*
 * See: http://msdn.microsoft.com/en-us/library/dd145119%28VS.85%29.aspx
 * This function was copied from the MSDN example.
 * It was then modified to send the BMP data rather than save to disk
 * It was then modified to conver the BMP to JPEG and send
 * Now its realy big.
 */
int bmp2jpeg(PBYTE buf, int quality, BYTE ** buf_jpeg, DWORD * buf_jpeg_size )
{

	// Convert to JPEG stuff
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;
    cjpeg_source_ptr src_mgr;
    JDIMENSION num_scanlines;


	// JPEG conversion start here..'
	// buf is a pointer to a BMP in memory.

	/* Initialize JPEG parameters.
     * Much of this may be overridden later.
     * We need to provide some value for jpeg_set_defaults() to work.
     */

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);
    cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
    jpeg_set_defaults(&cinfo);

	src_mgr = jinit_read_bmp(&cinfo); //Returns a cjpeg_source_ptr but is really bmp_source_ptr...

	src_mgr->input_buf = buf;
	src_mgr->read_offset = 0;
    /* Read the input file header to obtain file size & colorspace. */

	start_input_bmp(&cinfo, src_mgr);

    jpeg_default_colorspace(&cinfo);

	// TODO: accept options from the command line for grayscale and quality.
	/* Go GRAYSCALE */
	//jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
	/* Quality */
	jpeg_set_quality(&cinfo, quality, FALSE);

	// Write the compressed JPEG to memory: bug_jpeg
	jpeg_mem_dest(&cinfo, buf_jpeg, buf_jpeg_size);

    /* Start compressor */
    jpeg_start_compress(&cinfo, TRUE);

	/* Process data */
	while (cinfo.next_scanline < cinfo.image_height) {
		num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
		(void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
	}

	/* Finish compression and release memory */
	(*src_mgr->finish_input) (&cinfo, src_mgr);
	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);

    return 1;
}
Esempio n. 6
0
///////////////////////////////////////////////////////////////
//
// JpegEncode
//
// XRGB to jpeg
//
///////////////////////////////////////////////////////////////
bool JpegEncode ( uint uiWidth, uint uiHeight, uint uiQuality, const void* pData, uint uiDataSize, CBuffer& outBuffer )
{
    // Validate
    if ( uiDataSize == 0 || uiDataSize != uiWidth * uiHeight * 4 )
        return false;

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    unsigned long memlen = 0;
    unsigned char *membuffer = NULL;
    jpeg_mem_dest (&cinfo,&membuffer,&memlen );

    cinfo.image_width = uiWidth;    /* image width and height, in pixels */
    cinfo.image_height = uiHeight;
    cinfo.input_components = 3;     /* # of color components per pixel */
    cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality (&cinfo, uiQuality, true);
    cinfo.dct_method = JDCT_IFAST;

    /* Start compressor */
    jpeg_start_compress(&cinfo, TRUE);

    /* Process data */
    CBuffer rowBuffer;
    rowBuffer.SetSize ( uiWidth * 3 );
    char* pRowTemp = rowBuffer.GetData ();

    JSAMPROW row_pointer[1];
    while (cinfo.next_scanline < cinfo.image_height)
    {
        BYTE* pRowSrc = (BYTE*)pData + cinfo.next_scanline * uiWidth * 4;
        for ( uint i = 0 ; i < uiWidth ; i++ )
        {
            pRowTemp[i*3+0] = pRowSrc[i*4+2];
            pRowTemp[i*3+1] = pRowSrc[i*4+1];
            pRowTemp[i*3+2] = pRowSrc[i*4+0];
        }
        row_pointer[0] = (JSAMPROW)pRowTemp;
        (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    /* Finish compression and release memory */
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    // Copy out data and free memory
    outBuffer = CBuffer ( membuffer, memlen );
    free ( membuffer );

    return true;
}
void VideoCompressorThread::stoppableRun()
{
    while(!shouldStop)
    {
        // JPEG-related stuff
        struct jpeg_compress_struct cinfo;
        struct jpeg_error_mgr       jerr;
        JSAMPROW                    row_pointer;
        unsigned char*              jpgBuf=NULL;
        unsigned long               jpgBufLen=0;

        unsigned char*              data;
        ChunkAttrib                 chunkAttrib;

        // Get raw image from the input buffer
        data = inpBuf->getChunk(&chunkAttrib);

        // Initialize JPEG
        cinfo.err = jpeg_std_error(&jerr);
        jpeg_create_compress(&cinfo);
        jpeg_mem_dest(&cinfo, &jpgBuf, &jpgBufLen);

        // Set the parameters of the output file
        cinfo.image_width = VIDEO_WIDTH;
        cinfo.image_height = VIDEO_HEIGHT;
        cinfo.input_components = (color ? 3 : 1);
        cinfo.in_color_space = (color ? JCS_RGB : JCS_GRAYSCALE);

        // Use default compression parameters
        jpeg_set_defaults(&cinfo);
        jpeg_set_quality(&cinfo, jpgQuality, TRUE);

        // Do the compression
        jpeg_start_compress(&cinfo, TRUE);

        // write one row at a time
        while(cinfo.next_scanline < cinfo.image_height)
        {
            row_pointer = (data + (cinfo.next_scanline * cinfo.image_width * (color ? 3 : 1)));
            jpeg_write_scanlines(&cinfo, &row_pointer, 1);
        }

        // clean up after we're done compressing
        jpeg_finish_compress(&cinfo);


        // Insert compressed image into the output buffer
        chunkAttrib.chunkSize = jpgBufLen;
        outBuf->insertChunk(jpgBuf, chunkAttrib);

        // The output buffer needs to be explicitly freed by the libjpeg client
        free(jpgBuf);
        jpeg_destroy_compress(&cinfo);
    }
}
ImageBuffer compress_jpeg(ImageConf imageConf, uint8_t * buffer, int out_width, int out_height)
{
    ImageBuffer             f;
    f.buffer              = NULL;
    f.size                = 0;
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];
    int row_stride;
    unsigned long outlen = OUTPUT_BUF_SIZE;
    unsigned char *outbuffer = malloc(outlen);
    if ( !buffer )
    {
      printf("Error buffer null\n");
      return f;
    }

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_mem_dest (&cinfo, &outbuffer, &outlen);

    cinfo.image_width = out_width;
    cinfo.image_height = out_height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    cinfo.write_JFIF_header = TRUE;
    cinfo.JFIF_major_version = 1;
    cinfo.JFIF_minor_version = 2;
    cinfo.density_unit = 1;
    cinfo.write_Adobe_marker = TRUE;

    jpeg_set_quality(&cinfo, imageConf.quality, imageConf.baseline);
    cinfo.optimize_coding = imageConf.optimize;
    cinfo.smoothing_factor = imageConf.smooth;

    jpeg_simple_progression(&cinfo);
    jpeg_start_compress(&cinfo, TRUE);

    row_stride = out_width * 3;
    while (cinfo.next_scanline < cinfo.image_height) 
    {
        row_pointer[0] = &buffer[cinfo.next_scanline * row_stride];
        (void)jpeg_write_scanlines(&cinfo, row_pointer,1);
    }

    my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo.dest;
    jpeg_finish_compress(&cinfo);
    f.buffer = outbuffer;
    f.size = outlen;
    jpeg_destroy_compress(&cinfo);
    return f;
}
Esempio n. 9
0
/**
 * Encodes an RGB-buffer to a JPEG.
 *
 * @param rgb_buffer An RGB image.
 * @param rgb_width Width of the image, pixels.
 * @param rgb_height Height of the image, pixels.
 * @param quality Quality: 0-100.
 * @param out_buffer Encoded image (JPEG) [must be freed by the called via `free`].
 * @param out_size Size of the encoded image, bytes.
 * @param out_msg An error message, if any [must be freed by the caller via `free`].
 * @return 0 if there is no error, otherwise a error code, see 'jerror.h' for details.
 */
int encode_jpeg(unsigned char* rgb_buffer, unsigned int rgb_width, unsigned int rgb_height, int quality, unsigned char** out_buffer, unsigned int* out_size, char** out_msg) {
  unsigned char* out_buffer_ret = NULL;
  unsigned long out_size_ret = 0;

  struct jpeg_compress_struct cinfo;

  struct basic_jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr.handler);
  jerr.handler.error_exit = handle_exit;
  if (setjmp(jerr.setjmp_buffer)) {
    int result = jerr.handler.msg_code;
    *out_msg = strdup(jerr.msg_str);

    jpeg_destroy_compress(&cinfo);

    if(out_buffer_ret) {
      free(out_buffer_ret);
    }

    return result;
  }

  jpeg_create_compress(&cinfo);

  cinfo.image_width = rgb_width;
  cinfo.image_height = rgb_height;
  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;

  jpeg_set_defaults(&cinfo);

  jpeg_set_quality(&cinfo, quality, TRUE);

  jpeg_mem_dest(&cinfo, &out_buffer_ret, &out_size_ret);

  jpeg_start_compress(&cinfo, TRUE);

  JSAMPROW row_pointer[1];
  int row_stride = rgb_width * 3;
  while (cinfo.next_scanline < cinfo.image_height) {
    row_pointer[0] = &rgb_buffer[cinfo.next_scanline * row_stride];
    jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);

  *out_buffer = out_buffer_ret;
  *out_size = (unsigned int)out_size_ret;

  return 0;
}
Esempio n. 10
0
void screenshotJPEG(char *filename, qbyte *screendata, int screenwidth, int screenheight)	//input is rgb NOT rgba
{
	qbyte	*buffer;
	vfsfile_t	*outfile;
	jpeg_error_mgr_wrapper jerr;
	struct jpeg_compress_struct cinfo;
	JSAMPROW row_pointer[1];

	if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY)))
	{
		FS_CreatePath (filename, FS_GAME);
		if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY)))
		{
			Con_Printf("Error opening %s\n", filename);
			return;
		}
	}

	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = jpeg_error_exit;
	if (setjmp(jerr.setjmp_buffer))
	{
		jpeg_destroy_compress(&cinfo);
		VFS_CLOSE(outfile);
		FS_Remove(filename, FS_GAME);
		Con_Printf("Failed to create jpeg\n");
		return;
	}
	jpeg_create_compress(&cinfo);

	buffer = screendata;
	
	jpeg_mem_dest(&cinfo, outfile);
	cinfo.image_width = screenwidth; 	
	cinfo.image_height = screenheight;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults(&cinfo);
	jpeg_set_quality (&cinfo, 75/*bound(0, (int) gl_image_jpeg_quality_level.value, 100)*/, true);
	jpeg_start_compress(&cinfo, true);

	while (cinfo.next_scanline < cinfo.image_height)
	{
	    *row_pointer = &buffer[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3];
	    jpeg_write_scanlines(&cinfo, row_pointer, 1);
	}

	jpeg_finish_compress(&cinfo);
	VFS_CLOSE(outfile);
	jpeg_destroy_compress(&cinfo);
}
Esempio n. 11
0
/* ---------------------------------------------------------------------------
**  convert yuyv -> jpeg
** -------------------------------------------------------------------------*/
unsigned long yuyv2jpeg(char* image_buffer, unsigned int width, unsigned int height, unsigned int quality)
{
	struct jpeg_error_mgr jerr;
	struct jpeg_compress_struct cinfo;	
	jpeg_create_compress(&cinfo);
	cinfo.image_width = width;
	cinfo.image_height = height;
	cinfo.input_components = 3;	
	cinfo.err = jpeg_std_error(&jerr);
	
	unsigned char* dest = NULL;
	unsigned long  destsize = 0;
	jpeg_mem_dest(&cinfo, &dest, &destsize);
	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, quality, TRUE);
	jpeg_start_compress(&cinfo, TRUE);

	unsigned char bufline[cinfo.image_width * 3]; 
	while (cinfo.next_scanline < cinfo.image_height) 
	{ 
		// convert line from YUYV -> YUV
		for (unsigned int i = 0; i < cinfo.image_width; i += 2) 
		{ 
			unsigned int base = cinfo.next_scanline*cinfo.image_width * 2 ;
			bufline[i*3  ] = image_buffer[base + i*2  ]; 
			bufline[i*3+1] = image_buffer[base + i*2+1]; 
			bufline[i*3+2] = image_buffer[base + i*2+3]; 
			bufline[i*3+3] = image_buffer[base + i*2+2]; 
			bufline[i*3+4] = image_buffer[base + i*2+1]; 
			bufline[i*3+5] = image_buffer[base + i*2+3]; 
		} 
		JSAMPROW row = bufline; 
		jpeg_write_scanlines(&cinfo, &row, 1); 
	}
	jpeg_finish_compress(&cinfo);
	if (dest != NULL)
	{
		if (destsize < width*height*2)
		{
			memcpy(image_buffer, dest, destsize);
		}
		else
		{
			LOG(WARN) << "Buffer to small size:" << width*height*2 << " " << destsize; 
		}
		free(dest);
	}
	jpeg_destroy_compress(&cinfo);
	
	return destsize;
}
Esempio n. 12
0
/**
int  write_jpeg_mem(unsigned char** buf, unsigned long* len, JPEGImage jp, int qulty)

jp の画像データを *bufに書き出す.*bufは要 free

@param[out]  buf    画像データが格納される.要 free
@param[out]  len    buf の長さ(Byte)が格納される.
@param       jp     保存する JPEGデータ
@param       qulty  保存のクオリティ 0〜100  100が最高画質

@retval ERROR_GRAPH_OPFILE  ファイルオープンエラー
@retval ERROR_GRAPH_HEADER  不正ファイル(JPEGファイルでない?)
@retval ERROR_GRAPH_MEMORY  メモリエラー
@retval ERROR_GRAPH_NODATA  jp にデータが無い
@retval ERROR_GRAPH_IVDARH  buf が NULL, or サポート外のチャンネル数(現在の所チャンネル数は 1か 3のみをサポート)
*/
int  write_jpeg_mem(unsigned char** buf, unsigned long* len, JPEGImage jp, int qulty)
{
	struct jpeg_compress_struct jdat;
	struct jpeg_error_mgr	    jerr;

	if (buf==NULL || len==NULL) return ERROR_GRAPH_IVDARG;
	if (jp.col!=1 && jp.col!=3) return ERROR_GRAPH_IVDARG;
	if (jp.gp==NULL || jp.img==NULL) return ERROR_GRAPH_NODATA;

	*len = jp.xs*jp.ys*jp.col;
	if (*len<=0) return ERROR_GRAPH_IVDARG;

	if (qulty>100)	qulty = 100;
	else if (qulty<0) qulty = 0;
	

	*buf = (unsigned char*)malloc(*len);
	if (*buf==NULL) {
		return ERROR_GRAPH_MEMORY;
	}

	jdat.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&jdat);

	jpeg_mem_dest(&jdat, buf, len);

	jdat.image_width	  = jp.xs;
	jdat.image_height	  = jp.ys;
	jdat.input_components = jp.col;
	if (jp.col==1) jdat.in_color_space = JCS_GRAYSCALE;
	else		   jdat.in_color_space = JCS_RGB;

	jpeg_set_quality (&jdat, qulty, TRUE);
	jpeg_set_defaults(&jdat);

	jpeg_start_compress (&jdat, TRUE);
	jpeg_write_scanlines(&jdat, jp.img, jp.ys);
	jpeg_finish_compress(&jdat);
	jpeg_destroy_compress(&jdat);

	if (*len<=0) {
		freeNull(*buf);
		return ERROR_GRAPH;
	}

	return 0;
}
Esempio n. 13
0
void write_jpeg_file2(const char* filename, char* data, int w, int h) {
  JSAMPLE* image_buffer = reinterpret_cast<JSAMPLE*>(data);
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  JSAMPROW row_pointer[1];  // pointer to JSAMPLE row[s]
  int row_stride = w * 3;   // JSAMPLEs per row in image_buffer

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

  uint8_t* outbuffer = nullptr;  // must be 0
  size_t outsize = 0;  // must be 0
  jpeg_mem_dest(&cinfo, &outbuffer, &outsize);

  cinfo.image_width = w;  // image width and height, in pixels
  cinfo.image_height = h;
  cinfo.input_components = 3;      // # of color components per pixel
  cinfo.in_color_space = JCS_RGB;  // colorspace of input image

  jpeg_set_defaults(&cinfo);
  jpeg_set_quality(&cinfo, config.quality,
                   TRUE);  // limit to baseline-JPEG values

  jpeg_start_compress(&cinfo, TRUE);

  while (cinfo.next_scanline < cinfo.image_height) {
    // jpeg_write_scanlines expects an array of pointers to scanlines.
    // Here the array is only one element long, but you could pass
    // more than one scanline at a time if that's more convenient.
    row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
    (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  // Finish compression
  jpeg_finish_compress(&cinfo);

  // release JPEG compression object
  // This is an important step since it will release a good deal of memory.
  jpeg_destroy_compress(&cinfo);

  // Write file
  write_file(filename, (const char*)outbuffer, outsize);

  // free the jpeg buffer
  free(outbuffer);
}
Esempio n. 14
0
// Take a buffer in RGBA format, has to skip 4th uchar
int encodeJPEG(unsigned char *inputbuffer, int width, int height, unsigned char **outputbuffer, unsigned long *outputsize, int quality) {
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr       jerr;
  JSAMPROW row_pointer[1];
  unsigned char *buf;
  if (quality > 100)
    quality = 100;

  // convert RGBA to RGB
  buf = malloc(sizeof(unsigned char)*width*height*3);
  size_t i;
  unsigned char* p = buf;
  for(i=0;i<width*height*4; i++) {
      if (i % 4 == 0)
        continue;
      *p = inputbuffer[i];
      p++;
  }

  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
  jpeg_mem_dest(&cinfo, outputbuffer, outputsize);
  cinfo.image_width      = width;
  cinfo.image_height     = height;
  cinfo.input_components = 3;
  cinfo.in_color_space   = JCS_RGB;

  jpeg_set_defaults(&cinfo); 
  jpeg_set_quality(&cinfo,quality,TRUE);
  jpeg_simple_progression(&cinfo);
  cinfo.optimize_coding = TRUE;

  jpeg_start_compress(&cinfo, TRUE);

  while (cinfo.next_scanline < cinfo.image_height) {
      row_pointer[0] = &buf[cinfo.next_scanline *  width * 3];
      jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  free(buf);
  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);

  return 0;
}
Esempio n. 15
0
int write_jpegmem_rgb(char * frame, unsigned short width, unsigned short height, unsigned char **outbuffer, long unsigned int *outlen, int quality)
{
  JSAMPROW row_ptr[1];
  unsigned short nbChannels = 3 ;
  struct jpeg_compress_struct jpeg;
  struct jpeg_error_mgr jerr;
  char *line, *image;
  int y, x, line_width;
  //*outbuffer = NULL;
  *outlen = 0;
  line =(char *) malloc((width * nbChannels) * sizeof(char));
  if (!line)
    return 0;
  jpeg.err = jpeg_std_error (&jerr);
  jpeg_create_compress (&jpeg);
  jpeg.image_width = width;
  jpeg.image_height= height;
  jpeg.input_components = nbChannels;
  jpeg.in_color_space = JCS_RGB;
  jpeg_set_defaults (&jpeg);
  jpeg_set_quality (&jpeg, quality, TRUE);
  jpeg.dct_method = JDCT_FASTEST;
  jpeg_mem_dest(&jpeg, outbuffer, outlen);
  jpeg_start_compress (&jpeg, TRUE);
  row_ptr[0] = (JSAMPROW) line;
  line_width = width * nbChannels;
  for (y = 0; y < height; y++) {
    for (x = 0; x < line_width; x++) {
      line[x]   = frame[x];
    }
    if (!jpeg_write_scanlines (&jpeg, row_ptr, 1)) {
      jpeg_destroy_compress (&jpeg);
      free (line);
      return 0;
    }
    frame += line_width;
  }
  jpeg_finish_compress (&jpeg);
  jpeg_destroy_compress (&jpeg);
  free (line);
  return 1;
}
Esempio n. 16
0
long jpeg_compress(char *src, unsigned char *dst, int width, int height, int quality)
{
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
	
  JSAMPROW row_pointer[1];

  long bufsize = 65000;

  // create jpeg data
  cinfo.err = jpeg_std_error( &jerr );
  jpeg_create_compress(&cinfo);
  jpeg_mem_dest(&cinfo, &dst, &bufsize);

  // set image parameters
  cinfo.image_width = width;
  cinfo.image_height = height;
  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;

  // set jpeg compression parameters to default
  jpeg_set_defaults(&cinfo);
  // and then adjust quality setting
  jpeg_set_quality(&cinfo, quality, TRUE);

  // start compress 
  jpeg_start_compress(&cinfo, TRUE);

  // feed data
  while (cinfo.next_scanline < cinfo.image_height) {
    row_pointer[0] = src + cinfo.next_scanline * cinfo.image_width * cinfo.input_components;
    jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  // finish compression
  jpeg_finish_compress(&cinfo);

  // destroy jpeg data
  jpeg_destroy_compress(&cinfo);

  return bufsize;
}
Esempio n. 17
0
size_t JPEGCoder::encode() {
    double t0 = now();
    int step_w = orig_w/(capture_pixel_skip+1), step_h = orig_h/(capture_pixel_skip+1); 
    for(int y=0;y<step_h;y++) {
        int img_y = y * (capture_pixel_skip+1);
        for(int x=0;x<step_w;x++) {
            int img_x = x * (capture_pixel_skip+1);
            unsigned char r,g,b,a;
            capture_img->getPixelRaw( img_x, img_y, &r,&g,&b,&a);
            sampary[y][x*3+0] = r;
            sampary[y][x*3+1] = g;
            sampary[y][x*3+2] = b;
        }
    }
    double t1 = now();
    
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress( &cinfo);
    //    jpeg_stdio_dest(&cinfo,jfp);
    unsigned long outsize;
    jpeg_mem_dest( &cinfo, &compressed, &outsize );
    cinfo.image_width = step_w;
    cinfo.image_height = step_h;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
    jpeg_set_defaults( &cinfo);
    jpeg_set_quality( &cinfo, jpeg_quality, true );
    jpeg_start_compress( &cinfo, true );
    jpeg_write_scanlines( &cinfo, sampary, step_h );
    jpeg_finish_compress( &cinfo );
    compressed_size = outsize;
    double t2 = now();

    if((t2-t1)>0.02) print("slow jpeg compress");
    if((t1-t0)>0.02) print("slow pixel copy");
    
    //    print("jpeg: time: %f, %f img:%d,%d", t1-t0, t2-t1, step_w, step_h);
    return outsize;
}
Esempio n. 18
0
static void init_libjpeg_cinfo(struct v4lconvert_data *data)
{
	struct jpeg_compress_struct cinfo;
	unsigned char *jpeg_header = NULL;
	unsigned long jpeg_header_size = 0;

	if (data->cinfo_initialized)
		return;

	/* Setup our error handling */
	jpeg_std_error(&data->jerr);
	data->jerr.error_exit = jerr_error_exit;
	data->jerr.emit_message = jerr_emit_message;

	/* Create a jpeg compression object with default params and write
	   default jpeg headers to a mem buffer, so that we can use them to
	   pre-fill a jpeg_decompress_struct with default quant and huffman
	   tables, so that libjpeg can be used to parse [m]jpg-s with
	   incomplete headers */
	cinfo.err = &data->jerr;
	cinfo.client_data = data;
	jpeg_create_compress(&cinfo);
	jpeg_mem_dest(&cinfo, &jpeg_header, &jpeg_header_size);
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults(&cinfo);
	jpeg_write_tables(&cinfo);
	jpeg_destroy_compress(&cinfo);

	/* Init the jpeg_decompress_struct */
	data->cinfo.err = &data->jerr;
	data->cinfo.client_data = data;
	jpeg_create_decompress(&data->cinfo);
	jpeg_mem_src(&data->cinfo, jpeg_header, jpeg_header_size);
	jpeg_read_header(&data->cinfo, FALSE);

	free(jpeg_header);
	data->cinfo_initialized = 1;
}
Esempio n. 19
0
    void encodeRGB8_to_JPEG(unsigned char *image, size_t width, size_t height, unsigned char **encoded, size_t *capacity)
    {

#if JPEG_LIB_VERSION >= 80

        /*! Compression parameters and scratch space pointers (allocated by the library). */
        struct jpeg_compress_struct cinfo;

        /*! The library error handler. */
        struct jpeg_error_mgr jerror;  cinfo.err = jpeg_std_error(&jerror);

        /*! Initialize the JPEG compression object. */
        jpeg_create_compress(&cinfo);

        /*! Specify the incoming image resolution, color space, and color space components. */
        cinfo.image_width = width;  cinfo.image_height = height;  cinfo.in_color_space = JCS_RGB;  cinfo.input_components = 3;

        /*! Fill in a sensible set of defaults. */
        jpeg_set_defaults(&cinfo);

        /*! Set the image quality. */
        jpeg_set_quality(&cinfo, 90, TRUE);

        /*! Specify the data source. */
        jpeg_mem_dest(&cinfo, encoded, capacity);

        /*! Compress and write the image into the target buffer. */
        compress(&cinfo, image);

        /*! At this point 'jerror.num_warnings' could be checked for corrupt-data warnings. */
        jpeg_destroy_compress(&cinfo);

#else  // JPEG_LIB_VERSION

        throw std::runtime_error("JPEG encoding into a memory buffer requires LibJPEG 8a or higher");

#endif // JPEG_LIB_VERSION

    }
Esempio n. 20
0
void encodeFrame( unsigned char *pixels, int index ) {
    
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_compress(&cinfo);

    size_t outsz = 1024*256;
    unsigned char *outbuf = (unsigned char*) MALLOC(outsz);
    jpeg_mem_dest(&cinfo, &outbuf, &outsz );

    cinfo.image_width = SCREEN_WIDTH;
    cinfo.image_height = SCREEN_HEIGHT;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults( &cinfo );
    jpeg_set_quality( &cinfo, 75, 1 );
    jpeg_start_compress( &cinfo, 1 );

    JSAMPROW row_pointer;
    int y=0;
    while( cinfo.next_scanline < cinfo.image_height ) {
        row_pointer = pixels + y * SCREEN_WIDTH * 3;
        jpeg_write_scanlines( &cinfo, &row_pointer, 1 );
        y++;
    }
    jpeg_finish_compress(&cinfo);

    printf( "outlen: %d\n", (int)outsz );
    char path[100];
    snprintf(path,sizeof(path), "out%02d.jpg", index );
    FILE *fp = fopen( path,"w");
    fwrite( outbuf, 1, outsz, fp);
    fclose(fp);
}
Esempio n. 21
0
static int save_jpeg(unsigned char **buf, size_t *len, int quality, unsigned char *data, int width, int height, int bpl)
{
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;
	unsigned char *b = NULL;
	unsigned long l = 0;
	JSAMPROW row_pointer[1];

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

	jpeg_mem_dest(&cinfo, &b, &l);

	cinfo.image_width = width;
	cinfo.image_height = height;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_EXT_RGB;

	jpeg_set_defaults(&cinfo);

	jpeg_set_quality(&cinfo, quality, TRUE);

	jpeg_start_compress(&cinfo, TRUE);

	while (cinfo.next_scanline < cinfo.image_height) {
		row_pointer[0] = (void*)&data[cinfo.next_scanline * bpl];
		(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
	}

	jpeg_finish_compress(&cinfo);

	*buf = b;
	*len = l;

	jpeg_destroy_compress(&cinfo);

	return 0;
}
Esempio n. 22
0
static bool ipl2jpeg(IplImage *frame, unsigned char **outbuffer, long unsigned int *outlen) {
	unsigned char *outdata = (uchar *) frame->imageData;
	struct jpeg_compress_struct cinfo = {0};
	struct jpeg_error_mgr jerr;
	JSAMPROW row_ptr[1];
	int row_stride;

	*outbuffer = NULL;
	*outlen = 0;

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);
	jpeg_mem_dest(&cinfo, outbuffer, outlen);

	cinfo.image_width = frame->width;
	cinfo.image_height = frame->height;
	cinfo.input_components = frame->nChannels;
	if ( frame->nChannels == 1 )
		cinfo.in_color_space = JCS_GRAYSCALE;
	else
		cinfo.in_color_space = JCS_RGB;

	jpeg_set_defaults(&cinfo);
	jpeg_start_compress(&cinfo, TRUE);
	row_stride = frame->width * frame->nChannels;

	while (cinfo.next_scanline < cinfo.image_height) {
		row_ptr[0] = &outdata[cinfo.next_scanline * row_stride];
		jpeg_write_scanlines(&cinfo, row_ptr, 1);
	}

	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);

	return true;

}
Esempio n. 23
0
unsigned char* LibJPEG::encode(unsigned char* imageBuffer, unsigned long buffSize, 
	const int width, const int height, const int quality, unsigned long &destSize)
{

	unsigned long buf_size = 0;
	unsigned char* buf = NULL;

	jpeg_mem_dest(&m_cinfo, &buf, &buf_size);

	m_cinfo.image_width = width;
	m_cinfo.image_height = height;
	m_cinfo.input_components = 3;
	m_cinfo.in_color_space = JCS_RGB;

	jpeg_set_defaults(&m_cinfo);

	m_cinfo.dct_method = JDCT_FLOAT;
	jpeg_set_quality(&m_cinfo, quality, true);

	jpeg_start_compress(&m_cinfo, TRUE);

	JSAMPROW row_pointer[1];
	int row_stride;
	row_stride = m_cinfo.image_width * m_cinfo.input_components;
	while (m_cinfo.next_scanline < m_cinfo.image_height)
	{
		row_pointer[0] = &imageBuffer[m_cinfo.next_scanline * m_cinfo.image_width * m_cinfo.input_components];
		jpeg_write_scanlines(&m_cinfo, row_pointer, 1);
	}

	jpeg_finish_compress(&m_cinfo);

	destSize = buf_size;

	return buf;
}
Esempio n. 24
0
int main(int argc, char *argv[])
{
	FILE *fin, *fout;
	uint16_t thumb[65536];
	uint8_t header[16];
	uint8_t jpeg_stripe[500000];
	uint8_t out[5000000];
	uint8_t jpeg_data[500000];
	int q, width, height;
	int thumbnail_width, thumbnail_height;
	char fname[256];
	char outname[256];
	struct jpeg_compress_struct cinfo;
	struct jpeg_decompress_struct dinfo;
	struct jpeg_error_mgr jcerr, jderr;
	JOCTET *jpeg_header = NULL;
	unsigned long jpeg_header_size = 0;
	int i, x, y, x1, y1, jpeg_data_size, jpeg_data_idx, eoi, size, ret;

	if (argc != 2) {
		printf("syntax: jl2005bcd_decompress (some raw file)\n");
		return 1;
	}

	fin = fopen(argv[1], "r");
	if(!fin) {
		printf("Error opening raw file. Exiting.\n");
		return 0;
	}

	if (!strchr(argv[1], 0x2e)) {
		fprintf(stderr,
			"\tIllegal input file.\n"
			"\tNo period in filename!\n"
			"\tExiting!\n");
		return 0;
	}
	i = strchr(argv[1], 0x2e) - argv[1];
	if (i < 4) {
		fprintf(stderr,
			"\tBasename of input file is too short!\n"
			"\tExiting!\n");
		return 0;
	}
	/* Finally, check whether the alleged input file really claims to be
	 * a gphoto2 raw file, at least by its name */
	if (strncmp("raw_", argv[1], 4)) {
		fprintf(stderr,
		"\tThe input does not even claim to be a raw file!\n"
		"\tExiting!\n");
		return 0;
	}
	/* To create the name(s) of the destination file(s), remove
	 * the prefix raw_ as the first step.
	 */

	strncpy(outname, argv[1] + 4, i - 4);
	strcat (outname, "r");
	fprintf (stderr, "Destination file will be called %s\n", outname);


	fread(header, 1, 16, fin);
	q = header[3] & 0x7f;
	height = header[4] * 8;
	width = header[5] * 8;
	printf("quality is %d\n", q);
	printf("size: %dx%d\n", width, height);
	switch (header[9]) {
	case 0xf0:
		thumbnail_width = 128;
		thumbnail_height = 120;
		break;
	case 0x60:
		thumbnail_width = 96;
		thumbnail_height = 64;
		break;
	default:
		thumbnail_width = 0;
		thumbnail_height = 0;
	}

	if(thumbnail_width) {
		sprintf(fname, "%s-thumb.ppm", outname);
		fout = fopen(fname, "w");
		if (!fin || !fout) {
			printf("still stupid!\n");
			return 1;
		}

		fread(thumb, 1, thumbnail_width * thumbnail_height * 2, fin);

		for (i = 0; i < thumbnail_width * thumbnail_height; i++) {
			thumb[i] = ntohs(thumb[i]);
			out[i * 3 + 0] = (thumb[i] & 0xf800) >> 8;
			out[i * 3 + 1] = (thumb[i] & 0x07e0) >> 3;
			out[i * 3 + 2] = (thumb[i] & 0x001f) << 3;
		}

		fprintf(fout, "P6\n%d %d\n255\n", thumbnail_width,
							thumbnail_height);
		fwrite(out, 1, thumbnail_width * thumbnail_height * 3, fout);
		fclose(fout);
	}
	/*
	 * And the fun begins, first of all create a dummy jpeg, which we use
	 * to get the headers from to feed to libjpeg when decompressing the
	 * stripes. This way we can use libjpeg's quant table handling
	 * (and built in default huffman tables).
	 */
	cinfo.err = jpeg_std_error (&jcerr);
	jpeg_create_compress (&cinfo);
	jpeg_mem_dest (&cinfo, &jpeg_header, &jpeg_header_size);
	cinfo.image_width = 16;
	cinfo.image_height = 16;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults (&cinfo);
	/* Make comp[0] (which will be green) 1x2 subsampled */
	cinfo.comp_info[0].h_samp_factor = 1;
	cinfo.comp_info[0].v_samp_factor = 2;
	/* Make comp[1] and [2] use huffman table and quanttable 0, as all
	 * components use luminance settings with the jl2005c/d/e */
	cinfo.comp_info[1].quant_tbl_no = 0;
	cinfo.comp_info[1].dc_tbl_no = 0;
	cinfo.comp_info[1].ac_tbl_no = 0;
	cinfo.comp_info[2].quant_tbl_no = 0;
	cinfo.comp_info[2].dc_tbl_no = 0;
	cinfo.comp_info[2].ac_tbl_no = 0;
	/* Apply the quality setting from the header */
	if (q <= 0)
		i = 5000;
	else if (q <= 50)
		i = 5000 / q;
	else if (q <= 100)
		i = 2 * (100 - q);
	else
		i = 0;
	jpeg_set_linear_quality(&cinfo, i, TRUE);

	jpeg_start_compress (&cinfo, TRUE);
	while( cinfo.next_scanline < cinfo.image_height ) {
		JOCTET row[16 * 3];
		JSAMPROW row_pointer[1] = { row };
		jpeg_write_scanlines (&cinfo, row_pointer, 1);
	}
	jpeg_finish_compress (&cinfo);
	jpeg_destroy_compress (&cinfo);

	JSAMPLE green[8 * 16];
	JSAMPLE red[8 * 8];
	JSAMPLE blue[8 * 8];
	JSAMPROW green_row_pointer[16];
	JSAMPROW red_row_pointer[8];
	JSAMPROW blue_row_pointer[8];

	for (i = 0; i < 16; i++)
		green_row_pointer[i] = green + i * 8;

	for (i = 0; i < 8; i++) {
		red_row_pointer[i] = red + i * 8;
		blue_row_pointer[i] = blue + i * 8;
	}

	JSAMPARRAY samp_image[3] = { green_row_pointer,
				     red_row_pointer,
				     blue_row_pointer };

	memcpy(jpeg_stripe, jpeg_header, JPEG_HEADER_SIZE);
	jpeg_stripe[JPEG_HEIGHT_OFFSET    ] = height >> 8;
	jpeg_stripe[JPEG_HEIGHT_OFFSET + 1] = height;
	jpeg_stripe[JPEG_HEIGHT_OFFSET + 2] = 0;
	jpeg_stripe[JPEG_HEIGHT_OFFSET + 3] = 8;
	free (jpeg_header);
	jpeg_data_size = fread(jpeg_data, 1, 500000, fin);
	jpeg_data_idx = 0;

	memset(out, 0, width * height * 3);

	dinfo.err = jpeg_std_error (&jderr);
	jpeg_create_decompress (&dinfo);
	for (x = 0; x < width; x += 16) {
		eoi = find_eoi(jpeg_data, jpeg_data_idx, jpeg_data_size);
		if (eoi < 0)
			return eoi;

		size = eoi - jpeg_data_idx;
		if ((JPEG_HEADER_SIZE + size) > sizeof(jpeg_stripe)) {
			printf("AAAIIIIII\n");
			return 1;
		}
		memcpy (jpeg_stripe + JPEG_HEADER_SIZE,
			jpeg_data + jpeg_data_idx, size);

		jpeg_mem_src (&dinfo, jpeg_stripe, JPEG_HEADER_SIZE + size);
		jpeg_read_header (&dinfo, TRUE);
		dinfo.raw_data_out = TRUE;
#if JPEG_LIB_VERSION >= 70
		dinfo.do_fancy_upsampling = FALSE;
#endif
		jpeg_start_decompress (&dinfo);
		for (y = 0; y < height; y += 16) {
			jpeg_read_raw_data (&dinfo, samp_image, 16);
			for (y1 = 0; y1 < 16; y1 += 2) {
				for (x1 = 0; x1 < 16; x1 += 2) {
					out[((y + y1 + 0) * width
							+ x + x1 + 0) * 3]
						= red[y1 * 4 + x1 / 2];
					out[((y + y1 + 0) * width
							+ x + x1 + 1) * 3 + 1]
						= green[y1 * 8 + x1 / 2];
					out[((y + y1 + 1) * width
							+ x + x1 + 0) * 3 + 1]
						= green[y1 * 8 + 8 + x1 / 2];
					out[((y + y1 + 1) * width
							+ x + x1 + 1) * 3 + 2]
						= blue[y1 * 4 + x1 / 2];
				}
			}
		}
		jpeg_finish_decompress (&dinfo);

		/* Set jpeg_data_idx for the next stripe */
		jpeg_data_idx = (jpeg_data_idx + size + 0x0f) & ~0x0f;
	}
	jpeg_destroy_decompress(&dinfo);

	ret = gp_ahd_interpolate(out, width, height, BAYER_TILE_BGGR);
	if (ret < 0) {
		printf("HEUH?\n");
		return ret;
	}
	white_balance (out, width*height, 1.6);
	sprintf(fname, "%s.ppm", outname);
	fout = fopen(fname, "w");
	if (!fout) {
		printf("stupid again?\n");
		return 1;
	}
	fprintf(fout, "P6\n%d %d\n255\n", width, height);
	fwrite(out, 1, width * height * 3, fout);
	fclose(fin);
	fclose(fout);
	return 0;
}
Esempio n. 25
0
prepare_for_pass (j_compress_ptr cinfo)
{
  my_master_ptr master = (my_master_ptr) cinfo->master;
  cinfo->trellis_passes = master->pass_number < master->pass_number_scan_opt_base;

  switch (master->pass_type) {
  case main_pass:
    /* Initial pass: will collect input data, and do either Huffman
     * optimization or data output for the first scan.
     */
    select_scan_parameters(cinfo);
    per_scan_setup(cinfo);
    if (! cinfo->raw_data_in) {
      (*cinfo->cconvert->start_pass) (cinfo);
      (*cinfo->downsample->start_pass) (cinfo);
      (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
    }
    (*cinfo->fdct->start_pass) (cinfo);
    (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
    (*cinfo->coef->start_pass) (cinfo,
				(master->total_passes > 1 ?
				 JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
    (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
    if (cinfo->optimize_coding) {
      /* No immediate data output; postpone writing frame/scan headers */
      master->pub.call_pass_startup = FALSE;
    } else {
      /* Will write frame/scan headers at first jpeg_write_scanlines call */
      master->pub.call_pass_startup = TRUE;
    }
    break;
#ifdef ENTROPY_OPT_SUPPORTED
  case huff_opt_pass:
    /* Do Huffman optimization for a scan after the first one. */
    select_scan_parameters(cinfo);
    per_scan_setup(cinfo);
    if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
      (*cinfo->entropy->start_pass) (cinfo, TRUE);
      (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
      master->pub.call_pass_startup = FALSE;
      break;
    }
    /* Special case: Huffman DC refinement scans need no Huffman table
     * and therefore we can skip the optimization pass for them.
     */
    master->pass_type = output_pass;
    master->pass_number++;
    /*FALLTHROUGH*/
#endif
  case output_pass:
    /* Do a data-output pass. */
    /* We need not repeat per-scan setup if prior optimization pass did it. */
    if (! cinfo->optimize_coding) {
      select_scan_parameters(cinfo);
      per_scan_setup(cinfo);
    }
    if (cinfo->optimize_scans) {
      master->saved_dest = cinfo->dest;
      cinfo->dest = NULL;
      master->scan_size[master->scan_number] = 0;
      jpeg_mem_dest(cinfo, &master->scan_buffer[master->scan_number], &master->scan_size[master->scan_number]);
      (*cinfo->dest->init_destination)(cinfo);
    }
    (*cinfo->entropy->start_pass) (cinfo, FALSE);
    (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
    /* We emit frame/scan headers now */
    if (master->scan_number == 0)
      (*cinfo->marker->write_frame_header) (cinfo);
    (*cinfo->marker->write_scan_header) (cinfo);
    master->pub.call_pass_startup = FALSE;
    break;
  case trellis_pass:
    if (master->pass_number%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 1 && cinfo->trellis_q_opt) {
      int i, j;

      for (i = 0; i < NUM_QUANT_TBLS; i++) {
        for (j = 1; j < DCTSIZE2; j++) {
          cinfo->norm_src[i][j] = 0.0;
          cinfo->norm_coef[i][j] = 0.0;
        }
      }
    }
    (*cinfo->entropy->start_pass) (cinfo, TRUE);
    (*cinfo->coef->start_pass) (cinfo, JBUF_REQUANT);
    master->pub.call_pass_startup = FALSE;
    break;
      
  default:
    ERREXIT(cinfo, JERR_NOT_COMPILED);
  }

  master->pub.is_last_pass = (master->pass_number == master->total_passes-1);

  /* Set up progress monitor's pass info if present */
  if (cinfo->progress != NULL) {
    cinfo->progress->completed_passes = master->pass_number;
    cinfo->progress->total_passes = master->total_passes;
  }
}
Esempio n. 26
0
int
main (int argc, char **argv)
{
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
  struct cdjpeg_progress_mgr progress;
#endif
  int file_index;
  cjpeg_source_ptr src_mgr;
  FILE * input_file;
  FILE * output_file = NULL;
  unsigned char *outbuffer = NULL;
  unsigned long outsize = 0;
  JDIMENSION num_scanlines;

  /* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND
  argc = ccommand(&argv);
#endif

  progname = argv[0];
  if (progname == NULL || progname[0] == 0)
    progname = "cjpeg";		/* in case C library doesn't provide it */

  /* Initialize the JPEG compression object with default error handling. */
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
  /* Add some application-specific error messages (from cderror.h) */
  jerr.addon_message_table = cdjpeg_message_table;
  jerr.first_addon_message = JMSG_FIRSTADDONCODE;
  jerr.last_addon_message = JMSG_LASTADDONCODE;

  /* Now safe to enable signal catcher. */
#ifdef NEED_SIGNAL_CATCHER
  enable_signal_catcher((j_common_ptr) &cinfo);
#endif

  /* Initialize JPEG parameters.
   * Much of this may be overridden later.
   * In particular, we don't yet know the input file's color space,
   * but we need to provide some value for jpeg_set_defaults() to work.
   */

  cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
  cinfo.use_moz_defaults = TRUE;
  jpeg_set_defaults(&cinfo);

  /* Scan command line to find file names.
   * It is convenient to use just one switch-parsing routine, but the switch
   * values read here are ignored; we will rescan the switches after opening
   * the input file.
   */

  file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);

#ifdef TWO_FILE_COMMANDLINE
  if (!memdst) {
    /* Must have either -outfile switch or explicit output file name */
    if (outfilename == NULL) {
      if (file_index != argc-2) {
        fprintf(stderr, "%s: must name one input and one output file\n",
                progname);
        usage();
      }
      outfilename = argv[file_index+1];
    } else {
      if (file_index != argc-1) {
        fprintf(stderr, "%s: must name one input and one output file\n",
                progname);
        usage();
      }
    }
  }
#else
  /* Unix style: expect zero or one file name */
  if (file_index < argc-1) {
    fprintf(stderr, "%s: only one input file\n", progname);
    usage();
  }
#endif /* TWO_FILE_COMMANDLINE */

  /* Open the input file. */
  if (file_index < argc) {
    if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
      fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
      exit(EXIT_FAILURE);
    }
  } else {
    /* default input file is stdin */
    input_file = read_stdin();
  }

  /* Open the output file. */
  if (outfilename != NULL) {
    if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
      fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
      exit(EXIT_FAILURE);
    }
  } else if (!memdst) {
    /* default output file is stdout */
    output_file = write_stdout();
  }

#ifdef PROGRESS_REPORT
  start_progress_monitor((j_common_ptr) &cinfo, &progress);
#endif

  /* Figure out the input file format, and set up to read it. */
  src_mgr = select_file_type(&cinfo, input_file);
  src_mgr->input_file = input_file;

  /* Read the input file header to obtain file size & colorspace. */
  (*src_mgr->start_input) (&cinfo, src_mgr);

  /* Now that we know input colorspace, fix colorspace-dependent defaults */
#if JPEG_RAW_READER
  if (!is_jpeg)
#endif
    jpeg_default_colorspace(&cinfo);

  /* Adjust default compression parameters by re-parsing the options */
  file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);

  /* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
  if (memdst)
    jpeg_mem_dest(&cinfo, &outbuffer, &outsize);
  else
#endif
    jpeg_stdio_dest(&cinfo, output_file);

  /* Start compressor */
  jpeg_start_compress(&cinfo, TRUE);

  /* Copy metadata */
  if (is_jpeg) {
    jpeg_saved_marker_ptr marker;
    
    /* In the current implementation, we don't actually need to examine the
     * option flag here; we just copy everything that got saved.
     * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
     * if the encoder library already wrote one.
     */
    for (marker = src_mgr->marker_list; marker != NULL; marker = marker->next) {
      if (cinfo.write_JFIF_header &&
          marker->marker == JPEG_APP0 &&
          marker->data_length >= 5 &&
          GETJOCTET(marker->data[0]) == 0x4A &&
          GETJOCTET(marker->data[1]) == 0x46 &&
          GETJOCTET(marker->data[2]) == 0x49 &&
          GETJOCTET(marker->data[3]) == 0x46 &&
          GETJOCTET(marker->data[4]) == 0)
        continue;			/* reject duplicate JFIF */
      if (cinfo.write_Adobe_marker &&
          marker->marker == JPEG_APP0+14 &&
          marker->data_length >= 5 &&
          GETJOCTET(marker->data[0]) == 0x41 &&
          GETJOCTET(marker->data[1]) == 0x64 &&
          GETJOCTET(marker->data[2]) == 0x6F &&
          GETJOCTET(marker->data[3]) == 0x62 &&
          GETJOCTET(marker->data[4]) == 0x65)
        continue;			/* reject duplicate Adobe */
      jpeg_write_marker(&cinfo, marker->marker, marker->data, marker->data_length);
    }
  }
  
  /* Process data */
  while (cinfo.next_scanline < cinfo.image_height) {
    num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
#if JPEG_RAW_READER
    if (is_jpeg)
      (void) jpeg_write_raw_data(&cinfo, src_mgr->plane_pointer, num_scanlines);
    else
#endif
      (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
  }

  /* Finish compression and release memory */
  (*src_mgr->finish_input) (&cinfo, src_mgr);
  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);

  /* Close files, if we opened them */
  if (input_file != stdin)
    fclose(input_file);
  if (output_file != stdout && output_file != NULL)
    fclose(output_file);

#ifdef PROGRESS_REPORT
  end_progress_monitor((j_common_ptr) &cinfo);
#endif

  if (memdst) {
    fprintf(stderr, "Compressed size:  %lu bytes\n", outsize);
    if (outbuffer != NULL)
      free(outbuffer);
  }

  /* All done. */
  exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
  return 0;			/* suppress no-return-value warnings */
}
Esempio n. 27
0
File: jpeg.c Progetto: omry/image
/*
 * save function
 *
 */
int libjpeg_(Main_save)(lua_State *L) {
  unsigned char *inmem = NULL;  /* destination memory (if saving to memory) */
  unsigned long inmem_size = 0;  /* destination memory size (bytes) */

  /* get args */
  const char *filename = luaL_checkstring(L, 1);
  THTensor *tensor = luaT_checkudata(L, 2, torch_Tensor);  
  THTensor *tensorc = THTensor_(newContiguous)(tensor);
  real *tensor_data = THTensor_(data)(tensorc);

  const int save_to_file = luaL_checkint(L, 3);

  THByteTensor* tensor_dest = NULL;
  if (save_to_file == 0) {
    tensor_dest = luaT_checkudata(L, 5, "torch.ByteTensor");
  }

  int quality = luaL_checkint(L, 4);
  if (quality < 0 || quality > 100) {
    luaL_error(L, "quality should be between 0 and 100");
  }

  /* jpeg struct */
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;

  /* pointer to raw image */
  unsigned char *raw_image = NULL;

  /* dimensions of the image we want to write */
  int width=0, height=0, bytes_per_pixel=0;
  int color_space=0;
  if (tensorc->nDimension == 3) {
    bytes_per_pixel = tensorc->size[0];
    height = tensorc->size[1];
    width = tensorc->size[2];
    if (bytes_per_pixel == 3) {
      color_space = JCS_RGB;
    } else if (bytes_per_pixel == 1) {
      color_space = JCS_GRAYSCALE;
    } else {
      luaL_error(L, "tensor should have 1 or 3 channels (gray or RGB)");
    }
  } else if (tensorc->nDimension == 2) {
    bytes_per_pixel = 1;
    height = tensorc->size[0];
    width = tensorc->size[1];
    color_space = JCS_GRAYSCALE;
  } else {
    luaL_error(L, "supports only 1 or 3 dimension tensors");
  }

  /* alloc raw image data */
  raw_image = (unsigned char *)malloc((sizeof (unsigned char))*width*height*bytes_per_pixel);

  /* convert tensor to raw bytes */
  int x,y,k;
  for (k=0; k<bytes_per_pixel; k++) {
    for (y=0; y<height; y++) {
      for (x=0; x<width; x++) {
        raw_image[(y*width+x)*bytes_per_pixel+k] = *tensor_data++;
      }
    }
  }

  /* this is a pointer to one row of image data */
  JSAMPROW row_pointer[1];
  FILE *outfile = NULL;
  if (save_to_file == 1) {
    outfile = fopen( filename, "wb" );
    if ( !outfile ) {
      luaL_error(L, "Error opening output jpeg file %s\n!", filename );
    }
  }

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

  /* specify data source (eg, a file) */
  if (save_to_file == 1) {
    jpeg_stdio_dest(&cinfo, outfile);
  } else {
    jpeg_mem_dest(&cinfo, &inmem, &inmem_size);
  }

  /* Setting the parameters of the output file here */
  cinfo.image_width = width;	
  cinfo.image_height = height;
  cinfo.input_components = bytes_per_pixel;
  cinfo.in_color_space = color_space;

  /* default compression parameters, we shouldn't be worried about these */
  jpeg_set_defaults( &cinfo );
  jpeg_set_quality(&cinfo, quality, (boolean)0);

  /* Now do the compression .. */
  jpeg_start_compress( &cinfo, TRUE );

  /* like reading a file, this time write one row at a time */
  while( cinfo.next_scanline < cinfo.image_height ) {
    row_pointer[0] = &raw_image[ cinfo.next_scanline * cinfo.image_width *  cinfo.input_components];
    jpeg_write_scanlines( &cinfo, row_pointer, 1 );
  }

  /* similar to read file, clean up after we're done compressing */
  jpeg_finish_compress( &cinfo );
  jpeg_destroy_compress( &cinfo );
  
  if (outfile != NULL) {
    fclose( outfile );
  }

  if (save_to_file == 0) {
    
    THByteTensor_resize1d(tensor_dest, inmem_size);  /* will fail if it's not a Byte Tensor */ 
    unsigned char* tensor_dest_data = THByteTensor_data(tensor_dest); 
    memcpy(tensor_dest_data, inmem, inmem_size);
    free(inmem);
  }

  /* some cleanup */
  free(raw_image);
  THTensor_(free)(tensorc);

  /* success code is 1! */
  return 1;
}
Esempio n. 28
0
void
JpegEncoder::encode()
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, &jpeg, &jpeg_len);

    if (offset.isNull()) {
        cinfo.image_width = width;
        cinfo.image_height = height;
    }
    else {
        cinfo.image_width = offset.w;
        cinfo.image_height = offset.h;
    }
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    cinfo.smoothing_factor = smoothing;
    jpeg_start_compress(&cinfo, TRUE);

    unsigned char *rgb_data;
    switch (buf_type) {
    case BUF_RGBA:
        rgb_data = rgba_to_rgb(data, width*height*4);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/rgba_to_rgb.";
        break;

    case BUF_BGRA:
        rgb_data = bgra_to_rgb(data, width*height*4);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/bgra_to_rgb.";
        break;

    case BUF_BGR:
        rgb_data = bgr_to_rgb(data, width*height*3);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/bgr_to_rgb.";
        break;

    case BUF_RGB:
        rgb_data = data;
        break;

    default:
        throw "Unexpected buf_type in JpegEncoder::encode";
    }

    JSAMPROW row_pointer;
    int start = 0;
    if (!offset.isNull()) {
        start = offset.y*width*3 + offset.x*3;
    }
    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer = &rgb_data[start + cinfo.next_scanline*3*width];
        jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    if (buf_type == BUF_BGR || buf_type == BUF_RGBA || buf_type == BUF_BGRA)
        free(rgb_data);
}
Esempio n. 29
0
int
main (int argc, char **argv)
{
  struct jpeg_decompress_struct srcinfo;
  struct jpeg_compress_struct dstinfo;
  struct jpeg_error_mgr jsrcerr, jdsterr;
#ifdef PROGRESS_REPORT
  struct cdjpeg_progress_mgr progress;
#endif
  jvirt_barray_ptr * src_coef_arrays;
  jvirt_barray_ptr * dst_coef_arrays;
  int file_index;
  /* We assume all-in-memory processing and can therefore use only a
   * single file pointer for sequential input and output operation.
   */
  FILE * fp;
  unsigned char *inbuffer = NULL;
  unsigned long insize = 0;
  unsigned char *outbuffer = NULL;
  unsigned long outsize = 0;

  /* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND
  argc = ccommand(&argv);
#endif

  progname = argv[0];
  if (progname == NULL || progname[0] == 0)
    progname = "jpegtran";      /* in case C library doesn't provide it */

  /* Initialize the JPEG decompression object with default error handling. */
  srcinfo.err = jpeg_std_error(&jsrcerr);
  jpeg_create_decompress(&srcinfo);
  /* Initialize the JPEG compression object with default error handling. */
  dstinfo.err = jpeg_std_error(&jdsterr);
  jpeg_create_compress(&dstinfo);
  dstinfo.use_moz_defaults = TRUE;

  /* Scan command line to find file names.
   * It is convenient to use just one switch-parsing routine, but the switch
   * values read here are mostly ignored; we will rescan the switches after
   * opening the input file.  Also note that most of the switches affect the
   * destination JPEG object, so we parse into that and then copy over what
   * needs to affects the source too.
   */

  file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
  jsrcerr.trace_level = jdsterr.trace_level;
  srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;

#ifdef TWO_FILE_COMMANDLINE
  /* Must have either -outfile switch or explicit output file name */
  if (outfilename == NULL) {
    if (file_index != argc-2) {
      fprintf(stderr, "%s: must name one input and one output file\n",
              progname);
      usage();
    }
    outfilename = argv[file_index+1];
  } else {
    if (file_index != argc-1) {
      fprintf(stderr, "%s: must name one input and one output file\n",
              progname);
      usage();
    }
  }
#else
  /* Unix style: expect zero or one file name */
  if (file_index < argc-1) {
    fprintf(stderr, "%s: only one input file\n", progname);
    usage();
  }
#endif /* TWO_FILE_COMMANDLINE */

  /* Open the input file. */
  if (file_index < argc) {
    if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) {
      fprintf(stderr, "%s: can't open %s for reading\n", progname, argv[file_index]);
      exit(EXIT_FAILURE);
    }
  } else {
    /* default input file is stdin */
    fp = read_stdin();
  }

#ifdef PROGRESS_REPORT
  start_progress_monitor((j_common_ptr) &dstinfo, &progress);
#endif

  /* Specify data source for decompression */
  memsrc = dstinfo.use_moz_defaults; /* needed to revert to original */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
  if (memsrc) {
    size_t nbytes;
    do {
      inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE);
      if (inbuffer == NULL) {
        fprintf(stderr, "%s: memory allocation failure\n", progname);
        exit(EXIT_FAILURE);
      }
      nbytes = JFREAD(fp, &inbuffer[insize], INPUT_BUF_SIZE);
      if (nbytes < INPUT_BUF_SIZE && ferror(fp)) {
        if (file_index < argc)
          fprintf(stderr, "%s: can't read from %s\n", progname,
                  argv[file_index]);
        else
          fprintf(stderr, "%s: can't read from stdin\n", progname);
      }
      insize += (unsigned long)nbytes;
    } while (nbytes == INPUT_BUF_SIZE);
    jpeg_mem_src(&srcinfo, inbuffer, insize);
  } else
#endif
    jpeg_stdio_src(&srcinfo, fp);

  /* Enable saving of extra markers that we want to copy */
  jcopy_markers_setup(&srcinfo, copyoption);

  /* Read file header */
  (void) jpeg_read_header(&srcinfo, TRUE);

  /* Any space needed by a transform option must be requested before
   * jpeg_read_coefficients so that memory allocation will be done right.
   */
#if TRANSFORMS_SUPPORTED
  /* Fail right away if -perfect is given and transformation is not perfect.
   */
  if (!jtransform_request_workspace(&srcinfo, &transformoption)) {
    fprintf(stderr, "%s: transformation is not perfect\n", progname);
    exit(EXIT_FAILURE);
  }
#endif

  /* Read source file as DCT coefficients */
  src_coef_arrays = jpeg_read_coefficients(&srcinfo);

  /* Initialize destination compression parameters from source values */
  jpeg_copy_critical_parameters(&srcinfo, &dstinfo);

  /* Adjust destination parameters if required by transform options;
   * also find out which set of coefficient arrays will hold the output.
   */
#if TRANSFORMS_SUPPORTED
  dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
                                                 src_coef_arrays,
                                                 &transformoption);
#else
  dst_coef_arrays = src_coef_arrays;
#endif

  /* Close input file, if we opened it.
   * Note: we assume that jpeg_read_coefficients consumed all input
   * until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
   * only consume more while (! cinfo->inputctl->eoi_reached).
   * We cannot call jpeg_finish_decompress here since we still need the
   * virtual arrays allocated from the source object for processing.
   */
  if (fp != stdin)
    fclose(fp);

  /* Open the output file. */
  if (outfilename != NULL) {
    if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) {
      fprintf(stderr, "%s: can't open %s for writing\n", progname, outfilename);
      exit(EXIT_FAILURE);
    }
  } else {
    /* default output file is stdout */
    fp = write_stdout();
  }

  /* Adjust default compression parameters by re-parsing the options */
  file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);

  /* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
  if (dstinfo.use_moz_defaults)
    jpeg_mem_dest(&dstinfo, &outbuffer, &outsize);
  else
#endif
    jpeg_stdio_dest(&dstinfo, fp);

  /* Start compressor (note no image data is actually written here) */
  jpeg_write_coefficients(&dstinfo, dst_coef_arrays);

  /* Copy to the output file any extra markers that we want to preserve */
  jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);

  /* Execute image transformation, if any */
#if TRANSFORMS_SUPPORTED
  jtransform_execute_transformation(&srcinfo, &dstinfo,
                                    src_coef_arrays,
                                    &transformoption);
#endif

  /* Finish compression and release memory */
  jpeg_finish_compress(&dstinfo);
  
  if (dstinfo.use_moz_defaults) {
    size_t nbytes;
    
    unsigned char *buffer = outbuffer;
    unsigned long size = outsize;
    if (insize < size) {
      size = insize;
      buffer = inbuffer;
    }

    nbytes = JFWRITE(fp, buffer, size);
    if (nbytes < size && ferror(fp)) {
      if (file_index < argc)
        fprintf(stderr, "%s: can't write to %s\n", progname,
                argv[file_index]);
      else
        fprintf(stderr, "%s: can't write to stdout\n", progname);
    }
  }
    
  jpeg_destroy_compress(&dstinfo);
  (void) jpeg_finish_decompress(&srcinfo);
  jpeg_destroy_decompress(&srcinfo);

  /* Close output file, if we opened it */
  if (fp != stdout)
    fclose(fp);

#ifdef PROGRESS_REPORT
  end_progress_monitor((j_common_ptr) &dstinfo);
#endif

  /* All done. */
  exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS);
  return 0;                     /* suppress no-return-value warnings */
}
Esempio n. 30
0
bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile, 
                                         unsigned char* &bufferout, unsigned int &bufferoutSize)
{
  //Encode raw data from buffer, save to destbuffer
  struct jpeg_compress_struct cinfo;
  struct my_error_mgr jerr;
  JSAMPROW row_pointer[1];
  long unsigned int outBufSize = width * height;
  unsigned char* src = bufferin;
  unsigned char* rgbbuf, *src2, *dst2;

  if(bufferin == NULL)
  {
    CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface no buffer");
    return false;
  }

  m_thumbnailbuffer = (unsigned char*) malloc(outBufSize); //Initial buffer. Grows as-needed.
  if (m_thumbnailbuffer == NULL)
  {
    CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface error allocating memory for image buffer");
    return false;
  }

  if(format == XB_FMT_RGB8)
  {
    rgbbuf = bufferin;
  }
  else if(format == XB_FMT_A8R8G8B8)
  {
    // create a copy for bgra -> rgb.
    rgbbuf = new unsigned char [(width * height * 3)];
    unsigned char* dst = rgbbuf;
    for (unsigned int y = 0; y < height; y++)
    {
      dst2 = dst;
      src2 = src;
      for (unsigned int x = 0; x < width; x++, src2 += 4)
      {
        *dst2++ = src2[2];
        *dst2++ = src2[1];
        *dst2++ = src2[0];
      }
      dst += width * 3;
      src += pitch;
    }
  }
  else
  {
    CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format");
    free(m_thumbnailbuffer);
    return false;
  }

  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = jpeg_error_exit;
  jpeg_create_compress(&cinfo);

  if (setjmp(jerr.setjmp_buffer))
  {
    jpeg_destroy_compress(&cinfo);
    free(m_thumbnailbuffer);
    if(format != XB_FMT_RGB8)
      delete [] rgbbuf;
    return false;
  }
  else
  {
#if JPEG_LIB_VERSION < 80
    x_jpeg_mem_dest(&cinfo, &m_thumbnailbuffer, &outBufSize);
#else
    jpeg_mem_dest(&cinfo, &m_thumbnailbuffer, &outBufSize);
#endif
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 90, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    while (cinfo.next_scanline < cinfo.image_height)
    {
      row_pointer[0] = &rgbbuf[cinfo.next_scanline * width * 3];
      jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
  }
  if(format != XB_FMT_RGB8)
    delete [] rgbbuf;

  bufferout = m_thumbnailbuffer;
  bufferoutSize = outBufSize;

  return true;
}