Exemplo n.º 1
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;
  FILE * input_file;
  FILE * output_file;

  /* 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);

  /* Now safe to enable signal catcher.
   * Note: we assume only the decompression object will have virtual arrays.
   */
#ifdef NEED_SIGNAL_CATCHER
  enable_signal_catcher((j_common_ptr) &srcinfo);
#endif

  /* 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 ((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 {
    /* default output file is stdout */
    output_file = write_stdout();
  }

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

  /* Specify data source for decompression */
  jpeg_stdio_src(&srcinfo, input_file);

  /* 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
  jtransform_request_workspace(&srcinfo, &transformoption);
#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

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

  /* Specify data destination for compression */
  jpeg_stdio_dest(&dstinfo, output_file);

  /* 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);
  jpeg_destroy_compress(&dstinfo);
  (void) jpeg_finish_decompress(&srcinfo);
  jpeg_destroy_decompress(&srcinfo);

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

#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 */
}
Exemplo n.º 2
0
//--------------------------------------------------------------------------------
BitmapData* LoadJPEG(const Path& in_file)
{
	struct jpeg_decompress_struct cinfo;
	struct my_error_mgr jerr;
	
	FILE *infile;
	JSAMPARRAY buffer;

	FOPEN(&infile, in_file.GetData(), L("rb"));
								  
	if (infile == nullptr)
	{
		Assert(false);
		return nullptr;
	}

	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	if (setjmp(jerr.setjmp_buffer)) 
	{
		jpeg_destroy_decompress(&cinfo);
		fclose(infile);
		return nullptr;
	}

	jpeg_create_decompress(&cinfo);
	jpeg_stdio_src(&cinfo, infile);
	jpeg_read_header(&cinfo, true);
	jpeg_start_decompress(&cinfo);

	BufferFormat eFormat = BufferFormat::INVALID_FORMAT;
	switch (cinfo.out_color_space)
	{
	case JCS_EXT_ABGR:	eFormat = BufferFormat::RGBA_U32; break;
	case JCS_EXT_BGRA:	eFormat = BufferFormat::ARGB_U32; break;
	case JCS_EXT_RGBA:	eFormat = BufferFormat::ABGR_U32; break;
	case JCS_RGB:		eFormat = BufferFormat::BGR_U24; break;
	case JCS_EXT_BGR:	eFormat = BufferFormat::RGB_U24; break;
	//case JCS_RGB565:	eFormat = BufferFormat::R5G6B5_U16; break;
	case JCS_GRAYSCALE: eFormat = BufferFormat::A_U8; break;
	default:
		Assert(false);
		return nullptr;
	}

	BitmapData* pData = new BitmapData(cinfo.output_width, cinfo.output_height, eFormat);

	buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, pData->GetBufferPitch(), 1);

	while (cinfo.output_scanline < cinfo.output_height) 
	{
		jpeg_read_scanlines(&cinfo, buffer, 1);
		memcpy((u8*)&(pData->GetBuffer()[(cinfo.output_scanline-1) * pData->GetBufferPitch()]), buffer[0], pData->GetBufferPitch());
	}

	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	fclose(infile);

	Assert(jerr.pub.num_warnings == 0);

	return pData;
}
Exemplo n.º 3
0
int JpegDecode(char *srcbuf, char *dstbuf)
{
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
  struct cdjpeg_progress_mgr progress;
#endif
  int file_index;
  djpeg_dest_ptr dest_mgr = NULL;
  FILE * input_file;
  FILE * output_file;
  JDIMENSION num_scanlines;

  int argc=5;
  char *argv[5];
  char arg0[] = {"0"};
  char arg1[] = {"-bmp"};
  char arg2[] = {"-outfile"};
  char arg3[] = {"1.raw"};
  char arg4[] = {"E:\\WORK\\JPEGSR6\\JPEG-6B\\p3.jpg"};

  argv[0] = arg0;
  argv[1] = arg1;
  argv[2] = arg2;
  argv[3] = arg3;
  argv[4] = arg4;

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

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

  /* Initialize the JPEG decompression object with default error handling. */
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&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;

  /* Insert custom marker processor for COM and APP12.
   * APP12 is used by some digital camera makers for textual info,
   * so we provide the ability to display it as text.
   * If you like, additional APPn marker types can be selected for display,
   * but don't try to override APP0 or APP14 this way (see libjpeg.doc).
   */
  jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
  jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);

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

  /* 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.
   * (Exception: tracing level set here controls verbosity for COM markers
   * found during jpeg_read_header...)
   */

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

#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 */

#if 0
  /* 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 {
    /* default output file is stdout */
    output_file = write_stdout();
  }
#endif
  input_file = (FILE *)0xFF;
  output_file = (FILE *)0xFF;

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

  /* Specify data source for decompression */
  jpeg_stdio_src(&cinfo, input_file);

  cinfo.src_buffer = (UINT8 *)srcbuf;
  cinfo.src_position = 0;
  cinfo.dst_buffer = (UINT8 *)dstbuf;
  cinfo.dst_position = 0;


  /* Read file header, set default decompression parameters */
  (void) jpeg_read_header(&cinfo, TRUE);

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

  /* Initialize the output module now to let it override any crucial
   * option settings (for instance, GIF wants to force color quantization).
   */
  switch (requested_fmt) {
#ifdef BMP_SUPPORTED
  case FMT_BMP:
    dest_mgr = jinit_write_bmp(&cinfo, FALSE);
    break;
  case FMT_OS2:
    dest_mgr = jinit_write_bmp(&cinfo, TRUE);
    break;
#endif
#ifdef GIF_SUPPORTED
  case FMT_GIF:
    dest_mgr = jinit_write_gif(&cinfo);
    break;
#endif
#ifdef PPM_SUPPORTED
  case FMT_PPM:
    dest_mgr = jinit_write_ppm(&cinfo);
    break;
#endif
#ifdef RLE_SUPPORTED
  case FMT_RLE:
    dest_mgr = jinit_write_rle(&cinfo);
    break;
#endif
#ifdef TARGA_SUPPORTED
  case FMT_TARGA:
    dest_mgr = jinit_write_targa(&cinfo);
    break;
#endif
  default:
    ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT);
    break;
  }
  dest_mgr->output_file = output_file;

  /* Start decompressor */
  (void) jpeg_start_decompress(&cinfo);

  /* Write output file header */
  (*dest_mgr->start_output) (&cinfo, dest_mgr);

  /* Process data */
  while (cinfo.output_scanline < cinfo.output_height) {
    num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
					dest_mgr->buffer_height);
    (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
  }

#ifdef PROGRESS_REPORT
  /* Hack: count final pass as done in case finish_output does an extra pass.
   * The library won't have updated completed_passes.
   */
  progress.pub.completed_passes = progress.pub.total_passes;
#endif

  /* Finish decompression and release memory.
   * I must do it in this order because output module has allocated memory
   * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
   */
  (*dest_mgr->finish_output) (&cinfo, dest_mgr);
  (void) jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);

#if 0
  /* Close files, if we opened them */
  if (input_file != stdin)
    fclose(input_file);
  if (output_file != stdout)
    fclose(output_file);
#endif

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

#if 0
  /* All done. */
  exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
#endif
  return 0;			/* suppress no-return-value warnings */
}
Exemplo n.º 4
0
int main(int argc, char *argv[]) {
  const char *jpg_path;
  const char *yuv_path;
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  FILE *jpg_fd;
  int luma_width;
  int luma_height;
  int chroma_width;
  int chroma_height;
  int frame_width;
  int yuv_size;
  JSAMPLE *jpg_buffer;
  JSAMPROW yrow_pointer[16];
  JSAMPROW cbrow_pointer[8];
  JSAMPROW crrow_pointer[8];
  JSAMPROW *plane_pointer[3];
  unsigned char *yuv_buffer;
  int x;
  int y;
  FILE *yuv_fd;

  if (argc != 3) {
    fprintf(stderr, "Required arguments:\n");
    fprintf(stderr, "1. Path to JPG input file\n");
    fprintf(stderr, "2. Path to YUV output file\n");
    return 1;
  }

  /* Will check these for validity when opening via 'fopen'. */
  jpg_path = argv[1];
  yuv_path = argv[2];

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

  jpg_fd = fopen(jpg_path, "rb");
  if (!jpg_fd) {
    fprintf(stderr, "Invalid path to JPEG file!\n");
    return 1;
  }

  jpeg_stdio_src(&cinfo, jpg_fd);

  jpeg_read_header(&cinfo, TRUE);

  cinfo.raw_data_out = TRUE;
  cinfo.do_fancy_upsampling = FALSE;

  jpeg_start_decompress(&cinfo);

  luma_width = cinfo.output_width;
  luma_height = cinfo.output_height;

  chroma_width = (luma_width + 1) >> 1;
  chroma_height = (luma_height + 1) >> 1;

  yuv_size = luma_width*luma_height + 2*chroma_width*chroma_height;
  yuv_buffer = malloc(yuv_size);
  if (!yuv_buffer) {
    fclose(jpg_fd);
    fprintf(stderr, "Memory allocation failure!\n");
    return 1;
  }

  frame_width = (cinfo.output_width + (16 - 1)) & ~(16 - 1);

  jpg_buffer = malloc(frame_width*16 + 2*(frame_width/2)*8);
  if (!jpg_buffer) {
    fclose(jpg_fd);
    free(yuv_buffer);
    fprintf(stderr, "Memory allocation failure!\n");
    return 1;
  }

  plane_pointer[0] = yrow_pointer;
  plane_pointer[1] = cbrow_pointer;
  plane_pointer[2] = crrow_pointer;

  for (y = 0; y < 16; y++) {
    yrow_pointer[y] = &jpg_buffer[frame_width*y];
  }
  for (y = 0; y < 8; y++) {
    cbrow_pointer[y] = &jpg_buffer[frame_width*16 + (frame_width/2)*y];
    crrow_pointer[y] = &jpg_buffer[frame_width*16 + (frame_width/2)*(8 + y)];
  }

  while (cinfo.output_scanline < cinfo.output_height) {
    int luma_scanline;
    int chroma_scanline;

    luma_scanline = cinfo.output_scanline;
    chroma_scanline = (luma_scanline + 1) >> 1;

    jpeg_read_raw_data(&cinfo, plane_pointer, 16);

    for (y = 0; y < 16 && luma_scanline + y < luma_height; y++) {
      for (x = 0; x < luma_width; x++) {
        yuv_buffer[luma_width*(luma_scanline + y) + x] = yrow_pointer[y][x];
      }
    }
    for (y = 0; y < 8 && chroma_scanline + y < chroma_height; y++) {
      for (x = 0; x < chroma_width; x++) {
        yuv_buffer[luma_width*luma_height +
         chroma_width*(chroma_scanline + y) + x] = cbrow_pointer[y][x];
        yuv_buffer[luma_width*luma_height + chroma_width*chroma_height +
         chroma_width*(chroma_scanline + y) + x] = crrow_pointer[y][x];
      }
    }
  }

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

  fclose(jpg_fd);
  free(jpg_buffer);

  yuv_fd = fopen(yuv_path, "wb");
  if (!yuv_fd) {
    fprintf(stderr, "Invalid path to YUV file!");
    free(yuv_buffer);
    return 1;
  }
  if (fwrite(yuv_buffer, yuv_size, 1, yuv_fd) != 1) {
    fprintf(stderr, "Error writing yuv file\n");
  }

  fclose(yuv_fd);
  free(yuv_buffer);

  return 0;
}
Exemplo n.º 5
0
/* Shared library entry point */
GdkPixbuf *
gdk_pixbuf__jpeg_image_load (FILE *f)
{
	gint i;
	GdkPixbuf * volatile pixbuf = NULL;
	guchar *dptr;
	guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, 
                           * from the header file: 
                           * " Usually rec_outbuf_height will be 1 or 2, 
                           * at most 4."
			   */
	guchar **lptr;
	struct jpeg_decompress_struct cinfo;
	struct error_handler_data jerr;
	stdio_src_ptr src;

	/* setup error handler */
	cinfo.err = jpeg_std_error (&jerr.pub);
	jerr.pub.error_exit = fatal_error_handler;

	if (sigsetjmp (jerr.setjmp_buffer, 1)) {
		/* Whoops there was a jpeg error */
		if (pixbuf)
			gdk_pixbuf_unref (pixbuf);

		jpeg_destroy_decompress (&cinfo);
		return NULL;
	}

	/* load header, setup */
	jpeg_create_decompress (&cinfo);

	cinfo.src = (struct jpeg_source_mgr *)
	  (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
				  sizeof (stdio_source_mgr));
	src = (stdio_src_ptr) cinfo.src;
	src->buffer = (JOCTET *)
	  (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
				      JPEG_PROG_BUF_SIZE * sizeof (JOCTET));

	src->pub.init_source = stdio_init_source;
	src->pub.fill_input_buffer = stdio_fill_input_buffer;
	src->pub.skip_input_data = stdio_skip_input_data;
	src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
	src->pub.term_source = stdio_term_source;
	src->infile = f;
	src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
	src->pub.next_input_byte = NULL; /* until buffer loaded */

	jpeg_read_header (&cinfo, TRUE);
	jpeg_start_decompress (&cinfo);
	cinfo.do_fancy_upsampling = FALSE;
	cinfo.do_block_smoothing = FALSE;

	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
				 cinfo.out_color_components == 4 ? TRUE : FALSE, 
				 8, cinfo.output_width, cinfo.output_height);

	if (!pixbuf) {
		jpeg_destroy_decompress (&cinfo);
		return NULL;
	}

	dptr = pixbuf->pixels;

	/* decompress all the lines, a few at a time */

	while (cinfo.output_scanline < cinfo.output_height) {
		lptr = lines;
		for (i = 0; i < cinfo.rec_outbuf_height; i++) {
			*lptr++ = dptr;
			dptr += pixbuf->rowstride;
		}

		jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);

		switch (cinfo.out_color_space) {
		    case JCS_GRAYSCALE:
		      explode_gray_into_buf (&cinfo, lines);
		      break;
		    case JCS_RGB:
		      /* do nothing */
		      break;
		    case JCS_CMYK:
		      convert_cmyk_to_rgb (&cinfo, lines);
		      break;
		    default:
		      gdk_pixbuf_unref (pixbuf);
		      jpeg_destroy_decompress (&cinfo);
		      return NULL;
		}
	}

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

	return pixbuf;
}
Exemplo n.º 6
0
BYTE* CJpeg::ReadJPEGFile(LPCSTR lpstrFileName, UINT *uWidth, UINT *uHeight)
{
	*uWidth=0;
	*uHeight=0;

	
	//定义JPEG文件的解压信息
	struct jpeg_decompress_struct cinfo;
	
	//定义JPEG文件的错误信息
	struct my_error_mgr jerr;
	
	//定义缓冲区
	FILE * infile;		
	JSAMPARRAY buffer;	
	int row_stride;		
	char buf[250];

	
    //打开JPEG文件
	if ((infile = fopen(lpstrFileName, "rb")) == NULL) 
	{
		sprintf(buf, "JPEG :\nCan't open %s\n", lpstrFileName);
		m_strJPEGError = buf;
		return NULL;
	}

	
    //为JPEG文件解压对象分配内存并对其初始化

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



	if (setjmp(jerr.setjmp_buffer)) 
	{
		

		jpeg_destroy_decompress(&cinfo);
		fclose(infile);
		return NULL;
	}


	jpeg_create_decompress(&cinfo);


    //设定数据源 
	jpeg_stdio_src(&cinfo, infile);
    //读取JPEG文件参数

	(void) jpeg_read_header(&cinfo, TRUE);

      //开始解压
	(void) jpeg_start_decompress(&cinfo);
	
	BYTE *dataBuf;

	
	dataBuf=(BYTE *)new BYTE[cinfo.output_width * 3 * cinfo.output_height];
	if (dataBuf==NULL) 
	{

		m_strJPEGError = "JpegFile :\nOut of memory";

		jpeg_destroy_decompress(&cinfo);
		
		fclose(infile);

		return NULL;
	}


	*uWidth = cinfo.output_width;
	*uHeight = cinfo.output_height;
	

	row_stride = cinfo.output_width * cinfo.output_components;

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

	

	//读取扫描线
	while (cinfo.output_scanline < cinfo.output_height) 
	{
	
		(void) jpeg_read_scanlines(&cinfo, buffer, 1);
	
		if (cinfo.out_color_components==3) 
		{
			
			j_putRGBScanline(buffer[0], 
							*uWidth,
							dataBuf,
							cinfo.output_scanline-1);

		} 
		else if (cinfo.out_color_components==1) 
		{

		
			j_putGrayScanlineToRGB(buffer[0], 
								*uWidth,
								dataBuf,
								cinfo.output_scanline-1);

		}

	}


     //完成解压
	(void) jpeg_finish_decompress(&cinfo);

    //释放JPEG解压对象

	jpeg_destroy_decompress(&cinfo);

	
	fclose(infile);

	
	return dataBuf;
}
Exemplo n.º 7
0
int main(int argc, char **argv) 
{
  struct jpeg_decompress_struct dinfo;
  struct jpeg_compress_struct cinfo;
  struct my_error_mgr jcerr,jderr;
  JSAMPARRAY buf = NULL;
  jvirt_barray_ptr *coef_arrays = NULL;
  char marker_str[256];
  char tmpfilename[MAXPATHLEN],tmpdir[MAXPATHLEN];
  char newname[MAXPATHLEN], dest_path[MAXPATHLEN];
  volatile int i;
  int c,j, tmpfd, searchcount, searchdone;
  int opt_index = 0;
  long insize = 0, outsize = 0, lastsize = 0;
  int oldquality;
  double ratio;
  struct stat file_stat;
  jpeg_saved_marker_ptr cmarker; 
  unsigned char *outbuffer = NULL;
  size_t outbuffersize;
  char *outfname = NULL;
  FILE *infile = NULL, *outfile = NULL;
  int marker_in_count, marker_in_size;
  int compress_err_count = 0;
  int decompress_err_count = 0;
  long average_count = 0;
  double average_rate = 0.0, total_save = 0.0;


  if (rcsid)
  ; /* so compiler won't complain about "unused" rcsid string */

  umask(077);
  signal(SIGINT,own_signal_handler);
  signal(SIGTERM,own_signal_handler);

  /* initialize decompression object */
  dinfo.err = jpeg_std_error(&jderr.pub);
  jpeg_create_decompress(&dinfo);
  jderr.pub.error_exit=my_error_exit;
  jderr.pub.output_message=my_output_message;
  jderr.jump_set = 0;

  /* initialize compression object */
  cinfo.err = jpeg_std_error(&jcerr.pub);
  jpeg_create_compress(&cinfo);
  jcerr.pub.error_exit=my_error_exit;
  jcerr.pub.output_message=my_output_message;
  jcerr.jump_set = 0;


  if (argc<2) {
    if (!quiet_mode) fprintf(stderr,PROGRAMNAME ": file arguments missing\n"
			     "Try '" PROGRAMNAME " --help' for more information.\n");
    exit(1);
  }
 
  /* parse command line parameters */
  while(1) {
    opt_index=0;
    if ((c=getopt_long(argc,argv,"d:hm:nstqvfVpPoT:S:b",long_options,&opt_index))
	      == -1) 
      break;

    switch (c) {
    case 'm':
      {
        int tmpvar;

        if (sscanf(optarg,"%d",&tmpvar) == 1) {
	  quality=tmpvar;
	  if (quality < 0) quality=0;
	  if (quality > 100) quality=100;
	}
	else 
	  fatal("invalid argument for -m, --max");
      }
      break;
    case 'd':
      if (realpath(optarg,dest_path)==NULL || !is_directory(dest_path)) {
	fatal("invalid argument for option -d, --dest");
      }
      strncat(dest_path,DIR_SEPARATOR_S,sizeof(dest_path)-strlen(dest_path)-1);

      if (verbose_mode) 
	fprintf(stderr,"Destination directory: %s\n",dest_path);
      dest=1;
      break;
    case 'v':
      verbose_mode++;
      break;
    case 'h':
      print_usage();
      exit(0);
      break;
    case 'q':
      quiet_mode=1;
      break;
    case 't':
      totals_mode=1;
      break;
    case 'n':
      noaction=1;
      break;
    case 'f':
      force=1;
      break;
    case 'b':
      csv=1;
      quiet_mode=1;
      break;
    case '?':
      break;
    case 'V':
      print_version();
      exit(0);
      break;
    case 'o':
      overwrite_mode=1;
      break;
    case 'p':
      preserve_mode=1;
      break;
    case 'P':
      preserve_perms=1;
      break;
    case 's':
      save_exif=0;
      save_iptc=0;
      save_com=0;
      save_icc=0;
      save_xmp=0;
      break;
    case 'T':
      {
	int tmpvar;
	if (sscanf(optarg,"%d",&tmpvar) == 1) {
	  threshold=tmpvar;
	  if (threshold < 0) threshold=0;
	  if (threshold > 100) threshold=100;
	}
	else fatal("invalid argument for -T, --threshold");
      }
      break;
    case 'S':
      {
	unsigned int tmpvar;
	if (sscanf(optarg,"%u",&tmpvar) == 1) {
	  if (tmpvar > 0 && tmpvar < 100 && optarg[strlen(optarg)-1] == '%' ) {
	    target_size=-tmpvar;
	  } else {
	    target_size=tmpvar;
	  }
	  quality=100;
	}
	else fatal("invalid argument for -S, --size");
      }
      break;

    }
  }


  /* check for '-' option indicating input is from stdin... */
  i=1;
  while (argv[i]) {
    if (argv[i][0]=='-' && argv[i][1]==0) stdin_mode=1;
    i++;
  }

  if (stdin_mode) { stdout_mode=1; force=1; }
  if (stdout_mode) { logs_to_stdout=0; }

  if (all_normal && all_progressive)
    fatal("cannot specify both --all-normal and --all-progressive"); 

  if (verbose_mode) {
    if (quality>=0 && target_size==0) 
      fprintf(stderr,"Image quality limit set to: %d\n",quality);
    if (threshold>=0) 
      fprintf(stderr,"Compression threshold (%%) set to: %d\n",threshold);
    if (all_normal) 
      fprintf(stderr,"All output files will be non-progressive\n");
    if (all_progressive) 
      fprintf(stderr,"All output files will be progressive\n");
    if (target_size > 0) 
      fprintf(stderr,"Target size for output files set to: %u Kbytes.\n",
	      target_size);
    if (target_size < 0) 
      fprintf(stderr,"Target size for output files set to: %u%%\n",
	      -target_size);
  }


  /* loop to process the input files */
  i=1;  
  do {
    if (stdin_mode) {
      infile=stdin;
    } else {
      if (!argv[i][0]) continue;
      if (argv[i][0]=='-') continue;
      if (strlen(argv[i]) >= MAXPATHLEN) {
	warn("skipping too long filename: %s",argv[i]);
	continue;
      }

      if (!noaction) {
	/* generate tmp dir & new filename */
	if (dest) {
	  STRNCPY(tmpdir,dest_path,sizeof(tmpdir));
	  STRNCPY(newname,dest_path,sizeof(newname));
	  if (!splitname(argv[i],tmpfilename,sizeof(tmpfilename)))
	    fatal("splitname() failed for: %s",argv[i]);
	  strncat(newname,tmpfilename,sizeof(newname)-strlen(newname)-1);
	} else {
	  if (!splitdir(argv[i],tmpdir,sizeof(tmpdir))) 
	    fatal("splitdir() failed for: %s",argv[i]);
	  STRNCPY(newname,argv[i],sizeof(newname));
	}
      }
      
    retry_point:
      
      if (!is_file(argv[i],&file_stat)) {
	if (is_directory(argv[i])) 
	  warn("skipping directory: %s",argv[i]);
	else
	  warn("skipping special file: %s",argv[i]); 
	continue;
      }
      if ((infile=fopen(argv[i],"rb"))==NULL) {
	warn("cannot open file: %s", argv[i]);
	continue;
      }
    }

   if (setjmp(jderr.setjmp_buffer)) {
     /* error handler for decompress */
     jpeg_abort_decompress(&dinfo);
     fclose(infile);
     if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
     if (!quiet_mode || csv) 
       fprintf(LOG_FH,csv ? ",,,,,error\n" : " [ERROR]\n");
     decompress_err_count++;
     jderr.jump_set=0;
     continue;
   } else {
     jderr.jump_set=1;
   }

   if (!retry && (!quiet_mode || csv)) {
     fprintf(LOG_FH,csv ? "%s," : "%s ",(stdin_mode?"stdin":argv[i])); fflush(LOG_FH); 
   }

   /* prepare to decompress */
   global_error_counter=0;
   jpeg_save_markers(&dinfo, JPEG_COM, 0xffff);
   for (j=0;j<=15;j++) 
     jpeg_save_markers(&dinfo, JPEG_APP0+j, 0xffff);
   jpeg_stdio_src(&dinfo, infile);
   jpeg_read_header(&dinfo, TRUE); 

   /* check for Exif/IPTC/ICC/XMP markers */
   marker_str[0]=0;
   marker_in_count=0;
   marker_in_size=0;
   cmarker=dinfo.marker_list;

   while (cmarker) {
     marker_in_count++;
     marker_in_size+=cmarker->data_length;

     if (cmarker->marker == EXIF_JPEG_MARKER &&
	 !memcmp(cmarker->data,EXIF_IDENT_STRING,EXIF_IDENT_STRING_SIZE))
       strncat(marker_str,"Exif ",sizeof(marker_str)-strlen(marker_str)-1);

     if (cmarker->marker == IPTC_JPEG_MARKER)
       strncat(marker_str,"IPTC ",sizeof(marker_str)-strlen(marker_str)-1);

     if (cmarker->marker == ICC_JPEG_MARKER &&
	 !memcmp(cmarker->data,ICC_IDENT_STRING,ICC_IDENT_STRING_SIZE))
       strncat(marker_str,"ICC ",sizeof(marker_str)-strlen(marker_str)-1);

     if (cmarker->marker == XMP_JPEG_MARKER &&
	 !memcmp(cmarker->data,XMP_IDENT_STRING,XMP_IDENT_STRING_SIZE)) 
       strncat(marker_str,"XMP ",sizeof(marker_str)-strlen(marker_str)-1);

     cmarker=cmarker->next;
   }


   if (verbose_mode > 1) 
     fprintf(LOG_FH,"%d markers found in input file (total size %d bytes)\n",
	     marker_in_count,marker_in_size);
   if (!retry && (!quiet_mode || csv)) {
     fprintf(LOG_FH,csv ? "%dx%d,%dbit,%c," : "%dx%d %dbit %c ",(int)dinfo.image_width,
	     (int)dinfo.image_height,(int)dinfo.num_components*8,
	     (dinfo.progressive_mode?'P':'N'));

     if (!csv) {
       fprintf(LOG_FH,"%s",marker_str);
       if (dinfo.saw_Adobe_marker) fprintf(LOG_FH,"Adobe ");
       if (dinfo.saw_JFIF_marker) fprintf(LOG_FH,"JFIF ");
     }
     fflush(LOG_FH);
   }

   if ((insize=file_size(infile)) < 0)
     fatal("failed to stat() input file");

  /* decompress the file */
   if (quality>=0 && !retry) {
     jpeg_start_decompress(&dinfo);

     /* allocate line buffer to store the decompressed image */
     buf = malloc(sizeof(JSAMPROW)*dinfo.output_height);
     if (!buf) fatal("not enough memory");
     for (j=0;j<dinfo.output_height;j++) {
       buf[j]=malloc(sizeof(JSAMPLE)*dinfo.output_width*
		     dinfo.out_color_components);
       if (!buf[j]) fatal("not enough memory");
     }

     while (dinfo.output_scanline < dinfo.output_height) {
       jpeg_read_scanlines(&dinfo,&buf[dinfo.output_scanline],
			   dinfo.output_height-dinfo.output_scanline);
     }
   } else {
     coef_arrays = jpeg_read_coefficients(&dinfo);
   }

   if (!retry && !quiet_mode) {
     if (global_error_counter==0) fprintf(LOG_FH," [OK] ");
     else fprintf(LOG_FH," [WARNING] ");
     fflush(LOG_FH);
   }

   fclose(infile);
   infile=NULL;
     

   if (dest && !noaction) {
     if (file_exists(newname) && !overwrite_mode) {
       warn("target file already exists: %s\n",newname);
       jpeg_abort_decompress(&dinfo);
       if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
       continue;
     }
   }


   if (setjmp(jcerr.setjmp_buffer)) {
     /* error handler for compress failures */
     
     jpeg_abort_compress(&cinfo);
     jpeg_abort_decompress(&dinfo);
     if (!quiet_mode) fprintf(LOG_FH," [Compress ERROR]\n");
     if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
     compress_err_count++;
     jcerr.jump_set=0;
     continue;
   } else {
     jcerr.jump_set=1;
   }


   lastsize = 0;
   searchcount = 0;
   searchdone = 0;
   oldquality = 200;



  binary_search_loop:

   /* allocate memory buffer that should be large enough to store the output JPEG... */
   if (outbuffer) free(outbuffer);
   outbuffersize=insize + 32768;
   outbuffer=malloc(outbuffersize);
   if (!outbuffer) fatal("not enough memory");

   /* setup custom "destination manager" for libjpeg to write to our buffer */
   jpeg_memory_dest(&cinfo, &outbuffer, &outbuffersize, 65536);

   if (quality>=0 && !retry) {
     /* lossy "optimization" ... */

     cinfo.in_color_space=dinfo.out_color_space;
     cinfo.input_components=dinfo.output_components;
     cinfo.image_width=dinfo.image_width;
     cinfo.image_height=dinfo.image_height;
     jpeg_set_defaults(&cinfo); 
     jpeg_set_quality(&cinfo,quality,TRUE);
     if ( (dinfo.progressive_mode || all_progressive) && !all_normal )
       jpeg_simple_progression(&cinfo);
     cinfo.optimize_coding = TRUE;

     j=0;
     jpeg_start_compress(&cinfo,TRUE);
     
     /* write markers */
     write_markers(&dinfo,&cinfo);

     /* write image */
     while (cinfo.next_scanline < cinfo.image_height) {
       jpeg_write_scanlines(&cinfo,&buf[cinfo.next_scanline],
			    dinfo.output_height);
     }

   } else {
     /* lossless "optimization" ... */

     jpeg_copy_critical_parameters(&dinfo, &cinfo);
     if ( (dinfo.progressive_mode || all_progressive) && !all_normal )
       jpeg_simple_progression(&cinfo);
     cinfo.optimize_coding = TRUE;

     /* write image */
     jpeg_write_coefficients(&cinfo, coef_arrays);

     /* write markers */
     write_markers(&dinfo,&cinfo);

   }

   jpeg_finish_compress(&cinfo);
   outsize=outbuffersize;

   if (target_size != 0 && !retry) {
     /* perform (binary) search to try to reach target file size... */

     long osize = outsize/1024;
     long isize = insize/1024;
     long tsize = target_size;

     if (tsize < 0) { 
       tsize=((-target_size)*insize/100)/1024; 
       if (tsize < 1) tsize=1;
     }

     if (osize == tsize || searchdone || searchcount >= 8 || tsize > isize) {
       if (searchdone < 42 && lastsize > 0) {
	 if (abs(osize-tsize) > abs(lastsize-tsize)) {
	   if (verbose_mode) fprintf(LOG_FH,"(revert to %d)",oldquality);
	   searchdone=42;
	   quality=oldquality;
	   goto binary_search_loop;
	 }
       }
       if (verbose_mode) fprintf(LOG_FH," ");
       
     } else {
       int newquality;
       int dif = round(abs(oldquality-quality)/2.0);
       if (osize > tsize) {
	 newquality=quality-dif;
	 if (dif < 1) { newquality--; searchdone=1; }
	 if (newquality < 0) { newquality=0; searchdone=2; }
       } else {
	 newquality=quality+dif;
	 if (dif < 1) { newquality++; searchdone=3; }
	 if (newquality > 100) { newquality=100; searchdone=4; }
       }
       oldquality=quality;
       quality=newquality;

       if (verbose_mode) fprintf(LOG_FH,"(try %d)",quality);

       lastsize=osize;
       searchcount++;
       goto binary_search_loop;
     }
   } 

   if (buf) FREE_LINE_BUF(buf,dinfo.output_height);
   jpeg_finish_decompress(&dinfo);


   if (quality>=0 && outsize>=insize && !retry && !stdin_mode) {
     if (verbose_mode) fprintf(LOG_FH,"(retry w/lossless) ");
     retry=1;
     goto retry_point; 
   }

   retry=0;
   ratio=(insize-outsize)*100.0/insize;
   if (!quiet_mode || csv)
     fprintf(LOG_FH,csv ? "%ld,%ld,%0.2f," : "%ld --> %ld bytes (%0.2f%%), ",insize,outsize,ratio);
   average_count++;
   average_rate+=(ratio<0 ? 0.0 : ratio);

   if ((outsize < insize && ratio >= threshold) || force) {
        total_save+=(insize-outsize)/1024.0;
	if (!quiet_mode || csv) fprintf(LOG_FH,csv ? "optimized\n" : "optimized.\n");
        if (noaction) continue;

	if (stdout_mode) {
	  outfname=NULL;
	  if (fwrite(outbuffer,outbuffersize,1,stdout) != 1)
	    fatal("write failed to stdout");
	} else {
	  if (preserve_perms && !dest) {
	    /* make backup of the original file */
	    snprintf(tmpfilename,sizeof(tmpfilename),"%s.jpegoptim.bak",newname);
	    if (verbose_mode > 1 && !quiet_mode) 
	      fprintf(LOG_FH,"creating backup of original image as: %s\n",tmpfilename);
	    if (file_exists(tmpfilename))
	      fatal("backup file already exists: %s",tmpfilename);
	    if (copy_file(newname,tmpfilename))
	      fatal("failed to create backup of original file");
	    if ((outfile=fopen(newname,"wb"))==NULL)
	      fatal("error opening output file: %s", newname);
	    outfname=newname;
	  } else {
#ifdef HAVE_MKSTEMPS
	    /* rely on mkstemps() to create us temporary file safely... */  
	    snprintf(tmpfilename,sizeof(tmpfilename),
		     "%sjpegoptim-%d-%d.XXXXXX.tmp", tmpdir, (int)getuid(), (int)getpid());
	    if ((tmpfd = mkstemps(tmpfilename,4)) < 0) 
	      fatal("error creating temp file: mkstemps() failed");
	    if ((outfile=fdopen(tmpfd,"wb"))==NULL) 
#else
	      /* if platform is missing mkstemps(), try to create at least somewhat "safe" temp file... */  
	      snprintf(tmpfilename,sizeof(tmpfilename),
		       "%sjpegoptim-%d-%d.%d.tmp", tmpdir, (int)getuid(), (int)getpid(),time(NULL));
	    tmpfd=0;
	    if ((outfile=fopen(tmpfilename,"wb"))==NULL) 
#endif
	      fatal("error opening temporary file: %s",tmpfilename);
	    outfname=tmpfilename;
	  }

	  if (verbose_mode > 1 && !quiet_mode) 
	    fprintf(LOG_FH,"writing %lu bytes to file: %s\n",
		    (long unsigned int)outbuffersize, outfname);
	  if (fwrite(outbuffer,outbuffersize,1,outfile) != 1)
	    fatal("write failed to file: %s", outfname);
	  fclose(outfile);
	}

	if (outfname) {
	  
	  if (preserve_mode) {
	    /* preserve file modification time */
	    struct utimbuf time_save;
	    time_save.actime=file_stat.st_atime;
	    time_save.modtime=file_stat.st_mtime;
	    if (utime(outfname,&time_save) != 0) 
	      warn("failed to reset output file time/date");
	  }

	  if (preserve_perms && !dest) {
	    /* original file was already replaced, remove backup... */
	    if (delete_file(tmpfilename))
	      warn("failed to remove backup file: %s",tmpfilename);
	  } else {
	    /* make temp file to be the original file... */

	    /* preserve file mode */
	    if (chmod(outfname,(file_stat.st_mode & 0777)) != 0) 
	      warn("failed to set output file mode"); 

	    /* preserve file group (and owner if run by root) */
	    if (chown(outfname,
		      (geteuid()==0 ? file_stat.st_uid : -1),
		      file_stat.st_gid) != 0)
	      warn("failed to reset output file group/owner");

	    if (verbose_mode > 1 && !quiet_mode) 
	      fprintf(LOG_FH,"renaming: %s to %s\n",outfname,newname);
	    if (rename_file(outfname,newname)) fatal("cannot rename temp file");
	  }
	}
   } else {
     if (!quiet_mode || csv) fprintf(LOG_FH,csv ? "skipped\n" : "skipped.\n");
   }
   

  } while (++i<argc && !stdin_mode);


  if (totals_mode && !quiet_mode)
    fprintf(LOG_FH,"Average ""compression"" (%ld files): %0.2f%% (%0.0fk)\n",
	    average_count, average_rate/average_count, total_save);
  jpeg_destroy_decompress(&dinfo);
  jpeg_destroy_compress(&cinfo);

  return (decompress_err_count > 0 || compress_err_count > 0 ? 1 : 0);;
}
Exemplo n.º 8
0
Arquivo: jpeg.c Projeto: Eaeth/myNCCL
/*This returns an array for a 24 bit image.*/
u_char *decode_jpeg(const char *filename, fb_info *jpeg_inf)
{
	register JSAMPARRAY lineBuf;
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr err_mgr;
	int bytesPerPix;
	FILE *inFile;
	u_char *retBuf;
	
	inFile = fopen (filename, "rb");
	if (NULL == inFile)	{ 
		fprintf (stderr, "Error Open %s: %s\n",
			    filename, strerror(errno));
		return NULL;
	}

	cinfo.err = jpeg_std_error (&err_mgr);
	err_mgr.error_exit = jpeg_error_exit;	

	jpeg_create_decompress (&cinfo);
	jpeg_stdio_src (&cinfo, inFile);
	jpeg_read_header (&cinfo, 1);
	cinfo.do_fancy_upsampling = 0;
	cinfo.do_block_smoothing = 0;
	jpeg_start_decompress (&cinfo);

	/* 2010.2.6 and some... */
	jpeg_inf->w = cinfo.output_width;
	jpeg_inf->h = cinfo.output_height;

	short w,h;
	short *widthPtr = &w;
	short *heightPtr = &h;
	w = jpeg_inf->w;
	h = jpeg_inf->h;
	

	bytesPerPix = cinfo.output_components;

	lineBuf = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, (*widthPtr * bytesPerPix), 1);
	retBuf = (u_char *) malloc (3 * (*widthPtr * *heightPtr));
		
	if (NULL == retBuf) {
		perror (NULL);
		return NULL;
	}
		

	if (3 == bytesPerPix) {
		int y;
			
		for (y = 0; y < cinfo.output_height; ++y)	{	
			jpeg_read_scanlines (&cinfo, lineBuf, 1);
			memcpy ((retBuf + y * *widthPtr * 3),lineBuf[0],3 * *widthPtr);
		}
	}
	else if (1 == bytesPerPix) { 
		unsigned int col;
		int lineOffset = (*widthPtr * 3);
		int lineBufIndex;
		int x ;
		int y;
						
		for (y = 0; y < cinfo.output_height; ++y) {
			jpeg_read_scanlines (&cinfo, lineBuf, 1);
				
			lineBufIndex = 0;
			for (x = 0; x < lineOffset; ++x) {
				col = lineBuf[0][lineBufIndex];
			
				retBuf[(lineOffset * y) + x] = col;
				++x;
				retBuf[(lineOffset * y) + x] = col;
				++x;
				retBuf[(lineOffset * y) + x] = col;
				
				++lineBufIndex;
			}			
		}
	}
	else {
		fprintf (stderr, "Error: the number of color channels is %d.  This program only handles 1 or 3\n", bytesPerPix);
		return NULL;
	}
	jpeg_finish_decompress (&cinfo);
	jpeg_destroy_decompress (&cinfo);
	fclose (inFile);
			
	return retBuf;
}
void ZLEwlImageManager::convertImageDirectJpeg(const std::string &stringData, ZLImageData &data) const {
	struct jpeg_decompress_struct cinfo;
	JSAMPARRAY buffer;		/* Output row buffer */
	int row_stride;		/* physical row width in output buffer */

	struct my_error_mgr jerr;

	jpeg_create_decompress(&cinfo);

	jpeg_error_mgr errmgr;
	cinfo.err = jpeg_std_error(&errmgr);
	errmgr.error_exit = my_jpeg_error;	

	/* Establish the setjmp return context for my_error_exit to use. */
	if (setjmp(jerr.setjmp_buffer)) {
		/* If we get here, the JPEG code has signaled an error.
		 * We need to clean up the JPEG object, close the input file, and return.
		 */

		my_jpeg_src_free (&cinfo);
		jpeg_destroy_decompress(&cinfo);
		return;
	}

	my_jpeg_source_mgr *src;

	src = (my_jpeg_source_mgr *) new my_jpeg_source_mgr;
	cinfo.src = (struct jpeg_source_mgr *) src;

	src->len = stringData.length() + 2;
	src->buffer = new JOCTET[src->len];

	memcpy(src->buffer, (const unsigned char*)stringData.data(), stringData.length());
	src->buffer[stringData.length()] = (JOCTET) 0xFF;
	src->buffer[stringData.length() + 1] = (JOCTET) JPEG_EOI;

	src->pub.init_source = my_init_source;
	src->pub.fill_input_buffer = my_fill_input_buffer;
	src->pub.skip_input_data = my_skip_input_data;
	src->pub.resync_to_restart = my_resync_to_restart;
	src->pub.term_source = my_term_source;
	src->pub.bytes_in_buffer = src->len;
	src->pub.next_input_byte = src->buffer;

	(void) jpeg_read_header(&cinfo, true);

	data.init(cinfo.image_width, cinfo.image_height);

	cinfo.out_color_space = JCS_GRAYSCALE;

	(void) jpeg_start_decompress(&cinfo);

	row_stride = cinfo.output_width * cinfo.output_components;
	buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
 
	ZLIntegerOption myDitherAlgo(ZLCategoryKey::LOOK_AND_FEEL, "Options", "DitherAlgo", 0);
	register int dalgo = myDitherAlgo.value();
	char *c;
	while (cinfo.output_scanline < cinfo.output_height) {
		(void) jpeg_read_scanlines(&cinfo, buffer, 1);

		c = ((ZLEwlImageData&)data).getImageData() + cinfo.output_width * (cinfo.output_scanline - 1);

		if(dalgo == 1) {
			unsigned char *s = (unsigned char*)buffer[0];
			for(unsigned int i = 0; i < cinfo.output_width; i++)
				*c++ = Dither2BitColor(*s++, i, cinfo.output_scanline - 1);
		} else
			memcpy(c, (char*)buffer[0], cinfo.output_width);
	}

	(void) jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
}
Exemplo n.º 10
0
/* 
 * Create a gd-format image from the JPEG-format INFILE.  Returns the
 * image, or NULL upon error.
*/
gdImagePtr
gdImageCreateFromJpegCtx(gdIOCtx *infile)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    jmpbuf_wrapper jmpbufw;
    /* volatile so we can gdFree them after longjmp */
    volatile JSAMPROW row = 0;
    volatile gdImagePtr im = 0;
    JSAMPROW rowptr[1];
    int i, j, retval;
    JDIMENSION nrows;

#ifdef JPEG_DEBUG
    printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
    printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n",
	   JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
#endif

    memset(&cinfo, 0, sizeof(cinfo));
    memset(&jerr, 0, sizeof(jerr));

    cinfo.err = jpeg_std_error(&jerr);
    cinfo.client_data = &jmpbufw;
    if (setjmp(jmpbufw.jmpbuf) != 0) {
	/* we're here courtesy of longjmp */
	if (row)
	    gdFree(row);
	if (im)
	    gdImageDestroy(im);
	return 0;
    }

    cinfo.err->error_exit = fatal_jpeg_error;

    jpeg_create_decompress(&cinfo);

    jpeg_gdIOCtx_src(&cinfo, infile);

    retval = jpeg_read_header(&cinfo, TRUE);
    if (retval != JPEG_HEADER_OK)
	fprintf(stderr, "gd-jpeg: warning: jpeg_read_header returns"
		" %d, expected %d\n", retval, JPEG_HEADER_OK);

    if (cinfo.image_height > INT_MAX)
	fprintf(stderr, "gd-jpeg: warning: JPEG image height (%u) is"
		" greater than INT_MAX (%d) (and thus greater than"
		" gd can handle)", cinfo.image_height,
		INT_MAX);

    if (cinfo.image_width > INT_MAX)
	fprintf(stderr, "gd-jpeg: warning: JPEG image width (%u) is"
		" greater than INT_MAX (%d) (and thus greater than"
		" gd can handle)\n", cinfo.image_width, INT_MAX);

    im = gdImageCreate((int)cinfo.image_width,
		       (int)cinfo.image_height);
    if (im == 0) {
        fprintf(stderr, "gd-jpeg error: cannot allocate gdImage"
		" struct\n");
	goto error;
    }

    /*
     * Have the JPEG library quantize the number of image colors to
     * 256 maximum; force into RGB colorspace
     */
    cinfo.out_color_space = JCS_RGB;
    cinfo.quantize_colors = TRUE;
    cinfo.desired_number_of_colors = gdMaxColors;

    if (jpeg_start_decompress(&cinfo) != TRUE)
	fprintf(stderr, "gd-jpeg: warning: jpeg_start_decompress"
		" reports suspended data source\n");

#ifdef JPEG_DEBUG
    printf("gd-jpeg: JPEG image information:");
    if (cinfo.saw_JFIF_marker)
	printf(" JFIF version %d.%.2d",
	       (int)cinfo.JFIF_major_version,
	       (int)cinfo.JFIF_minor_version);
    else if (cinfo.saw_Adobe_marker)
	printf(" Adobe format");
    else
	printf(" UNKNOWN format");

    printf(" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
	   cinfo.image_height, cinfo.output_width,
	   cinfo.output_height, cinfo.data_precision);
    printf(" %s", (cinfo.progressive_mode ? "progressive" :
		   "baseline"));
    printf(" image, %d quantized colors, ",
	   cinfo.actual_number_of_colors);

    switch (cinfo.jpeg_color_space) {
    case JCS_GRAYSCALE:
	printf("grayscale");
	break;

    case JCS_RGB:
	printf("RGB");
	break;

    case JCS_YCbCr:
	printf("YCbCr (a.k.a. YUV)");
	break;

    case JCS_CMYK:
	printf("CMYK");
	break;

    case JCS_YCCK:
	printf("YCbCrK");
	break;

    default:
	printf("UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space);
	break;
    }
    printf(" colorspace\n");
    fflush(stdout);
#endif /* JPEG_DEBUG */

    gdImageInterlace(im, cinfo.progressive_mode != 0);

    im->colorsTotal = cinfo.actual_number_of_colors;
    if (cinfo.output_components != 1) {
	fprintf(stderr, "gd-jpeg: error: JPEG color quantization"
		" request resulted in output_components == %d"
		" (expected 1)\n",  cinfo.output_components);
	goto error;
    }

    for (i = 0; i < im->colorsTotal; i++) {
#if BITS_IN_JSAMPLE == 8
	im->red[i] = cinfo.colormap[0][i];
	im->green[i] = cinfo.colormap[1][i];
	im->blue[i] = cinfo.colormap[2][i];
#elif BITS_IN_JSAMPLE == 12
	im->red[i] = (cinfo.colormap[0][i] >> 4) & 0xff;
	im->green[i] = (cinfo.colormap[1][i] >> 4) & 0xff;
	im->blue[i] = (cinfo.colormap[2][i] >> 4) & 0xff;
#else
#error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12
#endif
	im->open[i] = 0;
#ifdef JPEG_DEBUG
	printf("gd-jpeg: gd colormap index %d set to (%d, %d, %d)\n", i,
	       im->red[i], im->green[i], im->blue[i]);
#endif
    }

    row = gdCalloc(cinfo.output_width, sizeof(JSAMPLE));
    if (row == 0) {
	fprintf(stderr, "gd-jpeg: error: unable to allocate row for"
		" JPEG scanline: gdCalloc returns NULL\n");
	goto error;
    }
    rowptr[0] = row;

    for (i = 0; i < cinfo.output_height; i++) {
	nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
	if (nrows != 1) {
	    fprintf(stderr, "gd-jpeg: error: jpeg_read_scanlines"
		    " returns %u, expected 1\n", nrows);
	    goto error;
	}

	for (j = 0; j < cinfo.output_width; j++)
	    im->pixels[i][j] = row[j];
    }

    if (jpeg_finish_decompress(&cinfo) != TRUE)
	fprintf(stderr, "gd-jpeg: warning: jpeg_finish_decompress"
		" reports suspended data source\n");


    jpeg_destroy_decompress(&cinfo);
    gdFree(row);
    return im;

error:
    jpeg_destroy_decompress(&cinfo);
    if (row)
	gdFree(row);
    if (im)
	gdImageDestroy(im);
    return 0;
}
Exemplo n.º 11
0
bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
{
    struct jpeg_decompress_struct cinfo;
    struct wx_error_mgr jerr;
    unsigned char *ptr;

    image->Destroy();
    cinfo.err = jpeg_std_error( &jerr.pub );
    jerr.pub.error_exit = wx_error_exit;

    if (!verbose)
        cinfo.err->output_message = wx_ignore_message;

    /* Establish the setjmp return context for wx_error_exit to use. */
    if (setjmp(jerr.setjmp_buffer)) {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      if (verbose)
        wxLogError(_("JPEG: Couldn't load - file is probably corrupted."));
      (cinfo.src->term_source)(&cinfo);
      jpeg_destroy_decompress(&cinfo);
      if (image->Ok()) image->Destroy();
      return false;
    }

    jpeg_create_decompress( &cinfo );
    wx_jpeg_io_src( &cinfo, stream );
    jpeg_read_header( &cinfo, TRUE );

    int bytesPerPixel;
    if ((cinfo.out_color_space == JCS_CMYK) || (cinfo.out_color_space == JCS_YCCK))
    {
        cinfo.out_color_space = JCS_CMYK;
        bytesPerPixel = 4;
    }
    else // all the rest is treated as RGB
    {
        cinfo.out_color_space = JCS_RGB;
        bytesPerPixel = 3;
    }

    jpeg_start_decompress( &cinfo );

    image->Create( cinfo.image_width, cinfo.image_height );
    if (!image->Ok()) {
        jpeg_finish_decompress( &cinfo );
        jpeg_destroy_decompress( &cinfo );
        return false;
    }
    image->SetMask( false );
    ptr = image->GetData();

    unsigned stride = cinfo.output_width * bytesPerPixel;
    JSAMPARRAY tempbuf = (*cinfo.mem->alloc_sarray)
                            ((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 );

    while ( cinfo.output_scanline < cinfo.output_height )
    {
        jpeg_read_scanlines( &cinfo, tempbuf, 1 );
        if (cinfo.out_color_space == JCS_RGB)
        {
            memcpy( ptr, tempbuf[0], stride );
            ptr += stride;
        }
        else // CMYK
        {
            const unsigned char* inptr = (const unsigned char*) tempbuf[0];
            for (size_t i = 0; i < cinfo.output_width; i++)
            {
                wx_cmyk_to_rgb(ptr, inptr);
                ptr += 3;
                inptr += 4;
            }
        }
    }

    jpeg_finish_decompress( &cinfo );
    jpeg_destroy_decompress( &cinfo );
    return true;
}
Exemplo n.º 12
0
void processimage (int i, 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(jpegbuffer==NULL){
		jpegbuffer = (*mycinfo.mem->alloc_sarray)
			((j_common_ptr) &mycinfo, JPOOL_IMAGE, row_stride, 1);
	}

	int y = 0;
	int *outp=rgb[i];
	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);
	
}
Exemplo n.º 13
0
int readJPEG(Image * im, fullPath * sfile)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE *infile;
    char filename[256];
    int scan_lines_to_be_read, scan_lines_read;
    unsigned int i, scanheight;
    unsigned char *data;
    JSAMPARRAY sarray;
    JOCTET *ptr = NULL;
    unsigned int size  = 0; 



#ifdef __Mac__
    unsigned char the_pcUnixFilePath[256];      // added by Kekus Digital
    Str255 the_cString;
    Boolean the_bReturnValue;
    CFStringRef the_FilePath;
    CFURLRef the_Url;           //till here
#endif

    //PrintError("%s", sfile->name);        

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

    // Prepare the library for reading the ICC profile, see its source code
    // for further information
    jpegICCSetupReadICCProfile(&cinfo);

    if (GetFullPath(sfile, filename))
        return -1;

#ifdef __Mac__
    CopyCStringToPascal(filename, the_cString); //Added by Kekus Digital
    the_FilePath =
        CFStringCreateWithPascalString(kCFAllocatorDefault, the_cString,
                                       kCFStringEncodingUTF8);
    the_Url =
        CFURLCreateWithFileSystemPath(kCFAllocatorDefault, the_FilePath,
                                      kCFURLHFSPathStyle, false);
    the_bReturnValue =
        CFURLGetFileSystemRepresentation(the_Url, true, the_pcUnixFilePath,
                                         256);

    strcpy(filename, the_pcUnixFilePath);       //till here
#endif

    if ((infile = fopen(filename, "rb")) == NULL) {
        PrintError("can't open %s", filename);
        return -1;
    }

    jpeg_stdio_src(&cinfo, infile);

    jpeg_read_header(&cinfo, TRUE);

    jpeg_start_decompress(&cinfo);

    SetImageDefaults(im);
    im->width = cinfo.output_width;
    im->height = cinfo.output_height;
    if (cinfo.output_components != 3)
    {
        PrintError("Image must be rgb");
        fclose(infile);
        return -1;
    }


    im->bitsPerPixel = 24;
    im->bytesPerLine = im->width * 3;
    im->dataSize = im->width * 4 * im->height;
    im->data = (unsigned char **) mymalloc((size_t) im->dataSize);
    if (im->data == NULL)
    {
        PrintError("Not enough memory");
        fclose(infile);
        return -1;
    }

    scanheight = cinfo.rec_outbuf_height;
    sarray = (JSAMPARRAY) malloc(scanheight * sizeof(JSAMPROW));

    scan_lines_to_be_read = im->height;
    data = *(im->data);

    while (scan_lines_to_be_read)
    {
        for (i = 0; i < scanheight; i++)
        {
            sarray[i] = (JSAMPROW) (data + i * im->bytesPerLine);
        }

        scan_lines_read = jpeg_read_scanlines(&cinfo, sarray, scanheight);

        scan_lines_to_be_read -= scan_lines_read;
        data += scan_lines_read * im->bytesPerLine;
    }

    // read ICC profile 
    
    if (jpegICCReadProfile(&cinfo, &ptr, &size)) {
        
        im->metadata.iccProfile.size = size;        
        im->metadata.iccProfile.data = (char*) ptr;
    }

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

    ThreeToFourBPP(im);
    free(sarray);


    fclose(infile);

    return 0;


}
Exemplo n.º 14
0
/**
 * jpgutl_decode_jpeg
 *  Purpose:  Decompress the jpeg data_in into the img_out buffer.
 *
 *  Parameters:
 *  jpeg_data_in     The jpeg data sent in
 *  jpeg_data_len    The length of the jpeg data
 *  width            The width of the image
 *  height           The height of the image
 *  img_out          Pointer to the image output
 *
 *  Return Values
 *    Success 0, Failure -1
 */
int jpgutl_decode_jpeg (unsigned char *jpeg_data_in, int jpeg_data_len,
                     unsigned int width, unsigned int height, unsigned char *volatile img_out)
{
    JSAMPARRAY      line;           /* Array of decomp data lines */
    unsigned char  *wline;          /* Will point to line[0] */
    unsigned int    i;
    unsigned char  *img_y, *img_cb, *img_cr;
    unsigned char   offset_y;

    struct jpeg_decompress_struct dinfo;
    struct jpgutl_error_mgr jerr;

    /* We set up the normal JPEG error routines, then override error_exit. */
    dinfo.err = jpeg_std_error (&jerr.pub);
    jerr.pub.error_exit = jpgutl_error_exit;
    /* Also hook the emit_message routine to note corrupt-data warnings. */
    jerr.original_emit_message = jerr.pub.emit_message;
    jerr.pub.emit_message = jpgutl_emit_message;
    jerr.warning_seen = 0;

    jpeg_create_decompress (&dinfo);

    /* Establish the setjmp return context for jpgutl_error_exit to use. */
    if (setjmp (jerr.setjmp_buffer)) {
        /* If we get here, the JPEG code has signaled an error. */
        jpeg_destroy_decompress (&dinfo);
        return -1;
    }

    jpgutl_buffer_src (&dinfo, jpeg_data_in, jpeg_data_len);

    jpeg_read_header (&dinfo, TRUE);

    //420 sampling is the default for YCbCr so no need to override.
    dinfo.out_color_space = JCS_YCbCr;
    dinfo.dct_method = JDCT_DEFAULT;
    guarantee_huff_tables(&dinfo);  /* Required by older versions of the jpeg libs */
    jpeg_start_decompress (&dinfo);

    if ((dinfo.output_width == 0) || (dinfo.output_height == 0)) {
        MOTION_LOG(WRN, TYPE_VIDEO, NO_ERRNO,_("Invalid JPEG image dimensions"));
        jpeg_destroy_decompress(&dinfo);
        return -1;
    }

    if ((dinfo.output_width != width) || (dinfo.output_height != height)) {
        MOTION_LOG(WRN, TYPE_VIDEO, NO_ERRNO
            ,_("JPEG image size %dx%d, JPEG was %dx%d")
            ,width, height, dinfo.output_width, dinfo.output_height);
        jpeg_destroy_decompress(&dinfo);
        return -1;
    }

    img_y  = img_out;
    img_cb = img_y + dinfo.output_width * dinfo.output_height;
    img_cr = img_cb + (dinfo.output_width * dinfo.output_height) / 4;

    /* Allocate space for one line. */
    line = (*dinfo.mem->alloc_sarray)((j_common_ptr) &dinfo, JPOOL_IMAGE,
                                       dinfo.output_width * dinfo.output_components, 1);

    wline = line[0];
    offset_y = 0;

    while (dinfo.output_scanline < dinfo.output_height) {
        jpeg_read_scanlines(&dinfo, line, 1);

        for (i = 0; i < (dinfo.output_width * 3); i += 3) {
            img_y[i / 3] = wline[i];
            if (i & 1) {
                img_cb[(i / 3) / 2] = wline[i + 1];
                img_cr[(i / 3) / 2] = wline[i + 2];
            }
        }

        img_y += dinfo.output_width;

        if (offset_y++ & 1) {
            img_cb += dinfo.output_width / 2;
            img_cr += dinfo.output_width / 2;
        }
    }

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

    /*
     * If there are too many warnings, this means that
     * only a partial image could be returned which would
     * trigger many false positive motion detections
    */
    if (jerr.warning_seen > 2) return -1;

    return 0;

}
Exemplo n.º 15
0
int res_create_surface_jpg(const char* name, gr_surface* pSurface) {
    GGLSurface* surface = NULL;
    int result = 0;
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    FILE* fp = fopen(name, "rb");
    if (fp == NULL) {
        char resPath[256];

        snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.jpg", name);
        resPath[sizeof(resPath)-1] = '\0';
        fp = fopen(resPath, "rb");
        if (fp == NULL) {
            result = -1;
            goto exit;
        }
    }

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

    /* Specify data source for decompression */
    jpeg_stdio_src(&cinfo, fp);

    /* Read file header, set default decompression parameters */
    if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK)
        goto exit;

    /* Start decompressor */
    (void) jpeg_start_decompress(&cinfo);

    size_t width = cinfo.image_width;
    size_t height = cinfo.image_height;
    size_t stride = 4 * width;
    size_t pixelSize = stride * height;

    surface = malloc(sizeof(GGLSurface) + pixelSize);
    if (surface == NULL) {
        result = -8;
        goto exit;
    }

    unsigned char* pData = (unsigned char*) (surface + 1);
    surface->version = sizeof(GGLSurface);
    surface->width = width;
    surface->height = height;
    surface->stride = width; /* Yes, pixels, not bytes */
    surface->data = pData;
    surface->format = GGL_PIXEL_FORMAT_RGBX_8888;

    int y;
    for (y = 0; y < (int) height; ++y) {
        unsigned char* pRow = pData + y * stride;
        jpeg_read_scanlines(&cinfo, &pRow, 1);

        int x;
        for(x = width - 1; x >= 0; x--) {
            int sx = x * 3;
            int dx = x * 4;
            unsigned char r = pRow[sx];
            unsigned char g = pRow[sx + 1];
            unsigned char b = pRow[sx + 2];
            unsigned char a = 0xff;
            pRow[dx    ] = r; // r
            pRow[dx + 1] = g; // g
            pRow[dx + 2] = b; // b
            pRow[dx + 3] = a;
        }
    }
    *pSurface = (gr_surface) surface;

exit:
    if (fp != NULL)
    {
        if (surface)
        {
            (void) jpeg_finish_decompress(&cinfo);
            if (result < 0)
            {
                free(surface);
            }
        }
        jpeg_destroy_decompress(&cinfo);
        fclose(fp);
    }
    return result;
}
Exemplo n.º 16
0
static int analyzer_jpeg_pload_analyze(struct analyzer *analyzer, struct analyzer_pload_buffer *pload, void *buffer, size_t buff_len) {


	struct analyzer_jpeg_pload_priv *priv = analyzer_pload_buffer_get_priv(pload);

	if (!priv) {
		priv = malloc(sizeof(struct analyzer_jpeg_pload_priv));
		if (!priv) {
			pom_oom(sizeof(struct analyzer_jpeg_pload_priv));
			return POM_ERR;
		}
		memset(priv, 0, sizeof(struct analyzer_jpeg_pload_priv));

		priv->pload_buff = buffer;
		priv->pload_buff_len = buff_len;
		
		// Setup error handler
		struct jpeg_error_mgr *jerr = malloc(sizeof(struct jpeg_error_mgr));
		if (!jerr) {
			free(priv);
			pom_oom(sizeof(struct jpeg_error_mgr));
			return POM_ERR;
		}
		memset(jerr, 0, sizeof(struct jpeg_error_mgr));
		priv->cinfo.err = jpeg_std_error(jerr);
		priv->cinfo.err->error_exit = analyzer_jpeg_lib_error_exit;

		// Allocate the decompressor
		jpeg_create_decompress(&priv->cinfo);

		priv->cinfo.client_data = priv;

#ifdef HAVE_LIBEXIF
		// Save APP1
		jpeg_save_markers(&priv->cinfo, JPEG_APP0 + 1, 0xFFFF);
#endif

		// Allocate the source
		
		struct jpeg_source_mgr *src = malloc(sizeof(struct jpeg_source_mgr));
		if (!src) {
			free(priv->cinfo.err);
			pom_oom(sizeof(struct jpeg_source_mgr));
			jpeg_destroy_decompress(&priv->cinfo);
			free(priv);
			return POM_ERR;
		}
		memset(src, 0, sizeof(struct jpeg_source_mgr));

		src->init_source = analyzer_jpeg_lib_init_source;
		src->fill_input_buffer = analyzer_jpeg_lib_fill_input_buffer;
		src->skip_input_data = analyzer_jpeg_lib_skip_input_data;
		src->resync_to_restart = jpeg_resync_to_restart;
		src->term_source = analyzer_jpeg_lib_term_source;
		priv->cinfo.src = src;


		analyzer_pload_buffer_set_priv(pload, priv);

	} else {
		priv->pload_buff = buffer;
		priv->pload_buff_len = buff_len;
	}


	if (priv->jpeg_lib_pos >= buff_len)
		// Nothing more to process
		return POM_OK;

	int res = POM_OK;
	if (!setjmp(priv->jmp_buff)) {

		if (priv->jpeg_lib_pos) {
			// It's not garanteed that buffer points to the
			// same memory area after each call, so we reset it here
			priv->cinfo.src->next_input_byte = buffer + priv->jpeg_lib_pos;
		}

		if (jpeg_read_header(&priv->cinfo, TRUE) == JPEG_SUSPENDED)
			return POM_OK; // Headers are incomplete

		struct data *data = analyzer_pload_buffer_get_data(pload);

		PTYPE_UINT16_SETVAL(data[analyzer_jpeg_pload_width].value, priv->cinfo.image_width);
		data_set(data[analyzer_jpeg_pload_width]);
		PTYPE_UINT16_SETVAL(data[analyzer_jpeg_pload_height].value, priv->cinfo.image_height);
		data_set(data[analyzer_jpeg_pload_height]);
		debug_jpeg("JPEG read header returned %u, image is %ux%u", res, priv->cinfo.image_width, priv->cinfo.image_height);

#ifdef HAVE_LIBEXIF		
		// Parse the exif data
		jpeg_saved_marker_ptr marker;
		for (marker = priv->cinfo.marker_list; marker && marker->marker != JPEG_APP0 + 1; marker = marker->next);

		if (marker) {
			ExifData *exif_data = exif_data_new_from_data(marker->data, marker->data_length);
			if (!exif_data) {
				pomlog(POMLOG_DEBUG "Unable to parse EXIF data");
			}

			exif_data_foreach_content(exif_data, analyzer_jpeg_exif_content_process, pload);

			exif_data_free(exif_data);
		}
#endif

		analyzer_pload_buffer_set_state(pload, analyzer_pload_buffer_state_analyzed);

	} else {
		pomlog(POMLOG_DEBUG "Error while parsing JPEG headers");
		res = POM_ERR;
	}

	free(priv->cinfo.err);
	free(priv->cinfo.src);
	jpeg_destroy_decompress(&priv->cinfo);
	free(priv);
	analyzer_pload_buffer_set_priv(pload, NULL);

	return res;
}
Exemplo n.º 17
0
int read_jpeg_file( char *filename )
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;

	JSAMPROW row_pointer[1];

	FILE *infile = fopen( filename, "rb" );
	unsigned long location = 0;
	long long j=0, i = 0;

	if ( !infile )
	{
		printf("Error opening jpeg file %s\n!", filename );
		return -1;
	}

	cinfo.err = jpeg_std_error( &jerr );

	jpeg_create_decompress( &cinfo );

	jpeg_stdio_src( &cinfo, infile );

	jpeg_read_header( &cinfo, TRUE );

	jpeg_start_decompress( &cinfo );

    width=cinfo.image_width;
	height=cinfo.image_height;
	bytes_per_pixel=cinfo.num_components;

	printf("components = %d\n", cinfo.num_components);

	raw_image = (unsigned char*)malloc( cinfo.output_width*cinfo.output_height*cinfo.num_components );
	raw_image2 = (unsigned char*)malloc( cinfo.output_width*cinfo.output_height*cinfo.num_components );

   unsigned char  **img = (unsigned char  **)malloc(height * sizeof(unsigned char  *));
    for (i=0; i<height; i++)
         img[i] = (unsigned char *)malloc(width*bytes_per_pixel * sizeof(unsigned char ));


   unsigned char  **oimg = (unsigned char  **)malloc(height * sizeof(unsigned char  *));
    for (i=0; i<height; i++)
         oimg[i] = (unsigned char *)malloc(width*bytes_per_pixel * sizeof(unsigned char ));

	row_pointer[0] = (unsigned char *)malloc( cinfo.output_width*cinfo.num_components );

	while( cinfo.output_scanline < cinfo.image_height )
	{
		jpeg_read_scanlines( &cinfo, row_pointer, 1 );
		for( i=0; i<cinfo.image_width*cinfo.num_components;i++)
			raw_image[location++] = row_pointer[0][i];
	}

    location=0;
    for(i=0;i<height;i++)
     for(j=0;j<width*bytes_per_pixel;j++)
     {
        img[i][j]=raw_image[location++];
     }

    int count=0;

   for(i=0;i<height;i++)
     for(j=0;j<width*bytes_per_pixel;j++)
     {
        if(i!=height-1&&j!=width*bytes_per_pixel-1)
        {
            oimg[i][j]=abs(img[i][j]*fs[0][0]+img[i][j+1]*fs[0][1]+img[i+1][j]*fs[1][0]+img[i+1][j+1]*fs[1][1])
                      +abs(img[i][j]*ft[0][0]+img[i][j+1]*ft[0][1]+img[i+1][j]*ft[1][0]+img[i+1][j+1]*ft[1][1]);
        }
        else
        {
            if(i!=height-1&&j==width*bytes_per_pixel-1)
            {
                oimg[i][j]=abs(img[i][j]*fs[0][0]+img[i+1][j]*fs[1][0])
                          +abs(img[i][j]*ft[0][0]+img[i+1][j]*ft[1][0]);
            }
            else
            if(i==height-1&&j!=width*bytes_per_pixel-1)
            {
                oimg[i][j]=abs(img[i][j]*fs[0][0]+img[i][j+1]*fs[0][1])
                          +abs(img[i][j]*ft[0][0]+img[i][j+1]*ft[0][1]);
            }
            else
            {
                oimg[i][j]=abs(img[i][j]*fs[0][0])+abs(img[i][j]*ft[0][0]);
            }


        }


     }

    printf("count is %d \n",count);

    location=0;
    for(i=0;i<height;i++)
     for(j=0;j<width*bytes_per_pixel;j++)
     {
        raw_image2[location++]=oimg[i][j];
     }


	jpeg_finish_decompress( &cinfo );
	jpeg_destroy_decompress( &cinfo );
	free( row_pointer[0] );
	fclose( infile );

	return 1;
}
Exemplo n.º 18
0
BOOL CImage::LoadBitmapFromJPEGFile(LPTSTR szFileName)
{
    BOOL bStatus = false;
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE* fp = NULL;
    JSAMPROW row = NULL;
    BITMAPINFO bmi;
    HDC hDC = NULL;

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

    _TFOPEN_S(fp, szFileName, _T("rb"));
    if (!fp)
    {
        goto cleanup;
    }

    jpeg_stdio_src(&cinfo, fp);

    jpeg_read_header(&cinfo, TRUE);

    jpeg_start_decompress(&cinfo);

    row = new BYTE[cinfo.output_width*3+10];

    hDC = GetDC(NULL);

    {
        CAutoLock lock(&m_csLock);
        if(m_bLoadCancelled)
            goto cleanup;
        m_hBitmap = CreateCompatibleBitmap(hDC, cinfo.output_width, cinfo.output_height);
    }

    memset(&bmi, 0, sizeof(bmi));
    bmi.bmiHeader.biSize = sizeof(bmi);
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biWidth = cinfo.output_width;
    bmi.bmiHeader.biHeight = cinfo.output_height;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = cinfo.output_width*cinfo.output_height*3;

    while (cinfo.output_scanline < cinfo.output_height)
    {
        jpeg_read_scanlines(&cinfo, &row, 1);

        if(cinfo.out_color_components==3)
        {
            // Convert RGB to BGR
            UINT i;
            for(i=0; i<cinfo.output_width; i++)
            {
                BYTE tmp = row[i*3+0];
                row[i*3+0] = row[i*3+2];
                row[i*3+2] = tmp;
            }
        }
        else
        {
            // Convert grayscale to BGR
            int i;
            for(i=cinfo.output_width-1; i>=0; i--)
            {
                row[i*3+0] = row[i];
                row[i*3+1] = row[i];
                row[i*3+2] = row[i];
            }
        }

        {
            CAutoLock lock(&m_csLock);
            int n = SetDIBits(hDC, m_hBitmap, cinfo.output_height-cinfo.output_scanline, 1, row, &bmi, DIB_RGB_COLORS);
            if(n==0)
                goto cleanup;
        }
    }

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

    bStatus = true;

cleanup:

    if(row)
        delete [] row;

    if(!bStatus)
    {
        Destroy();
    }

    if(fp!=NULL)
    {
        fclose(fp);
        fp = NULL;
    }

    return bStatus;
}
Exemplo n.º 19
0
uint8_t* ImageDecoder::decodeJPEGImpl(jpeg_source_mgr *src, jpeg_source_mgr *headerTables, uint32_t* width, uint32_t* height, bool* hasAlpha)
{
	struct jpeg_decompress_struct cinfo;
	struct error_mgr err;

	cinfo.err = jpeg_std_error(&err);
	err.error_exit = error_exit;

	if (setjmp(err.jmpBuf)) {
		return NULL;
	}

	jpeg_create_decompress(&cinfo);
	
	if (headerTables)
		cinfo.src = headerTables;
	else
		cinfo.src = src;

	//DefineBits tag may contain "abbreviated datastreams" (as
	//they are called in the libjpeg documentation), i.e. streams
	//with only compression tables and no image data. The first
	//jpeg_read_header accepts table-only streams.
	int headerStatus = jpeg_read_header(&cinfo, FALSE);

	if (headerTables)
	{
		// Must call init_source manually after switching src
		// Check this. Doesn't jpeg_read_header call
		// init_source anyway?
		cinfo.src = src;
		src->init_source(&cinfo);
	}

	//If the first jpeg_read_header got tables-only datastream,
	//a second call is needed to read the real image header.
	if (headerStatus == JPEG_HEADER_TABLES_ONLY) 
		jpeg_read_header(&cinfo, TRUE);

#ifdef JCS_EXTENSIONS
	//JCS_EXT_XRGB is a fast decoder that outputs alpha channel,
	//but is only available on libjpeg-turbo
	cinfo.out_color_space = JCS_EXT_XRGB;
	cinfo.output_components = 4;
#endif
	jpeg_start_decompress(&cinfo);

	*width = cinfo.output_width;
	*height = cinfo.output_height;
	if(cinfo.num_components != 3)
	{
		LOG(LOG_NOT_IMPLEMENTED,"Only RGB JPEG's are supported");
		/* TODO: is this the right thing for aborting? */
		jpeg_abort_decompress(&cinfo);
		jpeg_destroy_decompress(&cinfo);
		return NULL;
	}
	assert(cinfo.output_components == 3 || cinfo.output_components == 4);

	*hasAlpha = (cinfo.output_components == 4);

	int rowstride = cinfo.output_width * cinfo.output_components;
	JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, rowstride, 1);

	uint8_t* outData = new uint8_t[cinfo.output_height * rowstride];

	/* read one scanline at a time */
	int y=0;
	while (cinfo.output_scanline < cinfo.output_height) {
		jpeg_read_scanlines(&cinfo, buffer, 1);
		memcpy(&outData[y*rowstride], buffer[0], rowstride);
		y++;
	}

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

	return outData;
}
Exemplo n.º 20
0
GLuint loadTextureFromJPEG(const char* filename, int &width, int &height){
	AAsset* pAsset = NULL;


	struct jpeg_decompress_struct cInfo;
	struct jpeg_error_mgr jError;
	cInfo.err = jpeg_std_error(&jError); // register error handler 1
	jError.error_exit = _JpegError; // register error handler 2
	jpeg_create_decompress(&cInfo); // create a decompresser


	// load from asset
	pAsset = AAssetManager_open(mgr, filename, AASSET_MODE_UNKNOWN);
	if (!pAsset) {
		LOGD("!pAsset");
		return NULL;
	}

	unsigned char* ucharRawData = (unsigned char*)AAsset_getBuffer(pAsset);
	long myAssetLength = (long)AAsset_getLength(pAsset);

	// the jpeg_stdio_src alternative func, which is also included in IJG's lib.
	jpeg_mem_src(&cInfo, ucharRawData, myAssetLength);


	uint32_t* pTexUint;
	int yy;
	int  pixelSize, lineSize;
	char* lpbtBits;
	JSAMPLE tmp;
	int rectHeight, rectWidth;

	jpeg_read_header(&cInfo, TRUE); // read header
	jpeg_start_decompress(&cInfo); // start decompression
	//LOGD("cInfo %i - %i",cInfo.output_width,cInfo.output_height);
	width = cInfo.output_width;
	height = height = cInfo.output_height;
	pixelSize = cInfo.output_components;
	lineSize = width * pixelSize;

	pTexUint = (uint32_t*)calloc(sizeof(uint32_t), width * height);
	if (pTexUint == NULL){
		AAsset_close(pAsset);

		return NULL;
	}

	JSAMPLE* pSample = (JSAMPLE*)calloc(sizeof(JSAMPLE), lineSize + 10);
	if (!pSample){
		LOGE("Jpeg Lib","cannot alloc pSample");
		if (pTexUint) free(pTexUint);

		AAsset_close(pAsset);

		return NULL; //error
	}

	JSAMPROW buffer[1];
	buffer[0] = pSample;

	uint32_t* pPixelsUint = pTexUint;
	yy = 0;
	while(cInfo.output_scanline < cInfo.output_height){
		if(yy >= cInfo.output_height)
			break;

		jpeg_read_scanlines(&cInfo, buffer, 1);

		int xx;
		int x3;
		for(xx = 0, x3 = 0; xx < width; xx++, x3 += 3)
			pPixelsUint[xx] = make8888(buffer[0][x3], buffer[0][x3 + 1], buffer[0][x3 + 2], 0xff);

		pPixelsUint = (uint32_t*)pPixelsUint + width;
		yy++;
	}
	//LOGD("sizeof(*pPixelsUint) = %i", sizeof(*pPixelsUint));
	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pTexUint);


	jpeg_finish_decompress(&cInfo);
	jpeg_destroy_decompress(&cInfo);

	if (pSample) free(pSample);

	AAsset_close(pAsset);
	//free(pTexUint);
	return texture;
	//return (unsigned char*)pTexUint;

}
Exemplo n.º 21
0
bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
{
    wxCHECK_MSG( image, false, "NULL image pointer" );

    struct jpeg_decompress_struct cinfo;
    wx_error_mgr jerr;
    unsigned char *ptr;

    // save this before calling Destroy()
    const unsigned maxWidth = image->GetOptionInt(wxIMAGE_OPTION_MAX_WIDTH),
                   maxHeight = image->GetOptionInt(wxIMAGE_OPTION_MAX_HEIGHT);
    image->Destroy();

    cinfo.err = jpeg_std_error( &jerr );
    jerr.error_exit = wx_error_exit;

    if (!verbose)
        cinfo.err->output_message = wx_ignore_message;

    /* Establish the setjmp return context for wx_error_exit to use. */
    if (setjmp(jerr.setjmp_buffer)) {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      if (verbose)
      {
        wxLogError(_("JPEG: Couldn't load - file is probably corrupted."));
      }
      (cinfo.src->term_source)(&cinfo);
      jpeg_destroy_decompress(&cinfo);
      if (image->IsOk()) image->Destroy();
      return false;
    }

    jpeg_create_decompress( &cinfo );
    wx_jpeg_io_src( &cinfo, stream );
    jpeg_read_header( &cinfo, TRUE );

    int bytesPerPixel;
    if ((cinfo.out_color_space == JCS_CMYK) || (cinfo.out_color_space == JCS_YCCK))
    {
        cinfo.out_color_space = JCS_CMYK;
        bytesPerPixel = 4;
    }
    else // all the rest is treated as RGB
    {
        cinfo.out_color_space = JCS_RGB;
        bytesPerPixel = 3;
    }

    // scale the picture to fit in the specified max size if necessary
    if ( maxWidth > 0 || maxHeight > 0 )
    {
        unsigned& scale = cinfo.scale_denom;
        while ( (maxWidth && (cinfo.image_width / scale > maxWidth)) ||
                    (maxHeight && (cinfo.image_height / scale > maxHeight)) )
        {
            scale *= 2;
        }
    }

    jpeg_start_decompress( &cinfo );

    image->Create( cinfo.output_width, cinfo.output_height );
    if (!image->IsOk()) {
        jpeg_finish_decompress( &cinfo );
        jpeg_destroy_decompress( &cinfo );
        return false;
    }
    image->SetMask( false );
    ptr = image->GetData();

    unsigned stride = cinfo.output_width * bytesPerPixel;
    JSAMPARRAY tempbuf = (*cinfo.mem->alloc_sarray)
                            ((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 );

    while ( cinfo.output_scanline < cinfo.output_height )
    {
        jpeg_read_scanlines( &cinfo, tempbuf, 1 );
        if (cinfo.out_color_space == JCS_RGB)
        {
            memcpy( ptr, tempbuf[0], stride );
            ptr += stride;
        }
        else // CMYK
        {
            const unsigned char* inptr = (const unsigned char*) tempbuf[0];
            for (size_t i = 0; i < cinfo.output_width; i++)
            {
                wx_cmyk_to_rgb(ptr, inptr);
                ptr += 3;
                inptr += 4;
            }
        }
    }

    // set up resolution if available: it's part of optional JFIF APP0 chunk
    if ( cinfo.saw_JFIF_marker )
    {
        image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, cinfo.X_density);
        image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, cinfo.Y_density);

        // we use the same values for this option as libjpeg so we don't need
        // any conversion here
        image->SetOption(wxIMAGE_OPTION_RESOLUTIONUNIT, cinfo.density_unit);
    }

    jpeg_finish_decompress( &cinfo );
    jpeg_destroy_decompress( &cinfo );
    return true;
}
Exemplo n.º 22
0
 ~JPEGAutoClean() {
     if (cinfo_ptr) {
         jpeg_destroy_decompress(cinfo_ptr);
     }
 }
Exemplo n.º 23
0
int LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) {
  /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct jpeg_decompress_struct cinfo;
  /* We use our private extension JPEG error handler.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  /* This struct represents a JPEG error handler.  It is declared separately
   * because applications often want to supply a specialized error handler
   * (see the second half of this file for an example).  But here we just
   * take the easy way out and use the standard error handler, which will
   * print a message on stderr and call exit() if compression fails.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  struct jpeg_error_mgr jerr;
  /* More stuff */
  fileHandle_t infile;		/* source file */
  JSAMPARRAY buffer;		/* Output row buffer */
  int row_stride;		/* physical row width in output buffer */
  unsigned char *out;

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */

  FS_FOpenFileRead( filename, &infile, qfalse );
  if (infile == 0) {
    return 0;
  }

  /* Step 1: allocate and initialize JPEG decompression object */

  /* We have to set up the error handler first, in case the initialization
   * step fails.  (Unlikely, but it could happen if you are out of memory.)
   * This routine fills in the contents of struct jerr, and returns jerr's
   * address which we place into the link field in cinfo.
   */
  cinfo.err = jpeg_std_error(&jerr);

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

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src(&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header(&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

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

  /* 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.
   */ 
  /* JSAMPLEs per row in output buffer */
  row_stride = cinfo.output_width * cinfo.output_components;

  out = Z_Malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components);

  *pic = out;
  *width = cinfo.output_width;
  *height = cinfo.output_height;

  /* 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.
   */
  while (cinfo.output_scanline < cinfo.output_height) {
    /* jpeg_read_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could ask for
     * more than one scanline at a time if that's more convenient.
     */
	buffer = (JSAMPARRAY)out+(row_stride*cinfo.output_scanline);
    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  }

  /* Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio 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);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  FS_FCloseFile(infile);

  /* 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 1;
}
Exemplo n.º 24
0
bool CxImageJPG::Decode(CxFile * hFile)
{

	bool is_exif = false;
#if CXIMAGEJPG_SUPPORT_EXIF
	is_exif = DecodeExif(hFile);
#endif

	CImageIterator iter(this);
	/* This struct contains the JPEG decompression parameters and pointers to
	* working space (which is allocated as needed by the JPEG library).
	*/
	struct jpeg_decompress_struct cinfo;
	/* We use our private extension JPEG error handler. <CSC> */
	struct jpg_error_mgr jerr;
	jerr.buffer=info.szLastError;
	/* More stuff */
	JSAMPARRAY buffer;	/* Output row buffer */
	int row_stride;		/* physical row width in output buffer */

	/* In this example we want to open the input file before doing anything else,
	* so that the setjmp() error recovery below can assume the file is open.
	* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
	* requires it in order to read binary files.
	*/

	/* 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 = ima_jpeg_error_exit;

	/* Establish the setjmp return context for my_error_exit to use. */
#pragma warning(push)
#pragma warning(disable:4611)
	if (setjmp(jerr.setjmp_buffer)) {
#pragma warning(pop)
		/* If we get here, the JPEG code has signaled an error.
		* We need to clean up the JPEG object, close the input file, and return.
		*/
		jpeg_destroy_decompress(&cinfo);
		return 0;
	}
	/* Now we can initialize the JPEG decompression object. */
	jpeg_create_decompress(&cinfo);

	/* Step 2: specify data source (eg, a file) */
	//jpeg_stdio_src(&cinfo, infile);
	CxFileJpg src(hFile);
    cinfo.src = &src;

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

	/* Step 4 <chupeev> handle decoder options*/
	if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_GRAYSCALE) != 0)
		cinfo.out_color_space = JCS_GRAYSCALE;
	if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_QUANTIZE) != 0) {
		cinfo.quantize_colors = TRUE;
		cinfo.desired_number_of_colors = GetJpegQuality();
	}
	if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_DITHER) != 0)
		cinfo.dither_mode = m_nDither;
	if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_ONEPASS) != 0)
		cinfo.two_pass_quantize = FALSE;
	if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_NOSMOOTH) != 0)
		cinfo.do_fancy_upsampling = FALSE;

//<DP>: Load true color images as RGB (no quantize) 
/* Step 4: set parameters for decompression */
/*  if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) {
 *	cinfo.quantize_colors = TRUE;
 *	cinfo.desired_number_of_colors = 128;
 *}
 */ //</DP>

	// Set the scale <ignacio>
	cinfo.scale_denom = GetJpegScale();

	// Borrowed the idea from GIF implementation <ignacio>
	if (info.nEscape == -1) {
		// Return output dimensions only
		jpeg_calc_output_dimensions(&cinfo);
		head.biWidth = cinfo.output_width;
		head.biHeight = cinfo.output_height;
		info.dwType = CXIMAGE_FORMAT_JPG;
		jpeg_destroy_decompress(&cinfo);
		return true;
	}

	/* 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.
	*/
	//Create the image using output dimensions <ignacio>
	//Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
	Create(cinfo.output_width, cinfo.output_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);

	if (!pDib) longjmp(jerr.setjmp_buffer, 1);  //<DP> check if the image has been created

	if (is_exif){
#if CXIMAGEJPG_SUPPORT_EXIF
	if ((m_exifinfo.Xresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0))
		SetXDPI((long)(m_exifinfo.Xresolution/m_exifinfo.ResolutionUnit));
	if ((m_exifinfo.Yresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0))
		SetYDPI((long)(m_exifinfo.Yresolution/m_exifinfo.ResolutionUnit));
#endif
	} else {
		switch (cinfo.density_unit) {
		case 0:	// [andy] fix for aspect ratio...
			if((cinfo.Y_density > 0) && (cinfo.X_density > 0)){
				SetYDPI((long)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density))));
			}
			break;
		case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter
			SetXDPI((long)floor(cinfo.X_density * 2.54 + 0.5));
			SetYDPI((long)floor(cinfo.Y_density * 2.54 + 0.5));
			break;
		default:
			SetXDPI(cinfo.X_density);
			SetYDPI(cinfo.Y_density);
		}
	}

	if (cinfo.out_color_space==JCS_GRAYSCALE){
		SetGrayPalette();
		head.biClrUsed =256;
	} else {
		if (cinfo.quantize_colors){
			SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]);
			head.biClrUsed=cinfo.actual_number_of_colors;
		} else {
			head.biClrUsed=0;
		}
	}

	/* 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, 1);

	/* 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.
	*/
	iter.Upset();
	while (cinfo.output_scanline < cinfo.output_height) {

		if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
		
		(void) jpeg_read_scanlines(&cinfo, buffer, 1);
		// info.nProgress = (long)(100*cinfo.output_scanline/cinfo.output_height);
		//<DP> Step 6a: CMYK->RGB */ 
		if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
			BYTE k,*dst,*src;
			dst=iter.GetRow();
			src=buffer[0];
			for(long x3=0,x4=0; x3<(long)info.dwEffWidth && x4<row_stride; x3+=3, x4+=4){
				k=src[x4+3];
				dst[x3]  =(BYTE)((k * src[x4+2])/255);
				dst[x3+1]=(BYTE)((k * src[x4+1])/255);
				dst[x3+2]=(BYTE)((k * src[x4+0])/255);
			}
		} else {
			/* Assume put_scanline_someplace wants a pointer and sample count. */
			iter.SetRow(buffer[0], row_stride);
		}
			iter.PrevRow();
	}

	/* Step 7: Finish decompression */
	(void) jpeg_finish_decompress(&cinfo);
	/* We can ignore the return value since suspension is not possible
	* with the stdio data source.
	*/

	//<DP> Step 7A: Swap red and blue components
	// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
	if ((cinfo.num_components==3)&&(cinfo.quantize_colors==FALSE)){
		BYTE* r0=GetBits();
		for(long y=0;y<head.biHeight;y++){
			if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
			RGBtoBGR(r0,3*head.biWidth);
			r0+=info.dwEffWidth;
		}
	}

	/* 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 true;
}
Exemplo n.º 25
0
static int64_t
_get_jpeg_metadata(const char *path, char *name)
{
	ExifData *ed;
	ExifEntry *e = NULL;
	ExifLoader *l;
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE *infile;
	int width=0, height=0, thumb=0;
	char make[32], model[64] = {'\0'};
	char b[1024];
	struct stat file;
	int64_t ret;
	image_s *imsrc;
	metadata_t m;
	uint32_t free_flags = 0xFFFFFFFF;
	memset(&m, '\0', sizeof(metadata_t));

	//DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path);
	if ( stat(path, &file) != 0 )
		return 0;
	strip_ext(name);
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);

	/* MIME hard-coded to JPEG for now, until we add PNG support */
	m.mime = strdup("image/jpeg");

	l = exif_loader_new();
	exif_loader_write_file(l, path);
	ed = exif_loader_get_data(l);
	exif_loader_unref(l);
	if( !ed )
		goto no_exifdata;

	e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) )
	{
		m.date = strdup(exif_entry_get_value(e, b, sizeof(b)));
		if( strlen(m.date) > 10 )
		{
			m.date[4] = '-';
			m.date[7] = '-';
			m.date[10] = 'T';
		}
		else {
			free(m.date);
			m.date = NULL;
		}
	}
	else {
		/* One last effort to get the date from XMP */
		image_get_jpeg_date_xmp(path, &m.date);
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", m.date);

	e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
	if( e )
	{
		strncpyt(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
		e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
		if( e )
		{
			strncpyt(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));
			if( !strcasestr(model, make) )
				snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b)));
			m.creator = escape_tag(trim(model), 1);
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * model: %s\n", model);

	e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION);
	if( e )
	{
		switch( exif_get_short(e->data, exif_data_get_byte_order(ed)) )
		{
		case 3:
			m.rotation = 180;
			break;
		case 6:
			m.rotation = 90;
			break;
		case 8:
			m.rotation = 270;
			break;
		default:
			m.rotation = 0;
			break;
		}
	}

	if( ed->size )
	{
		/* We might need to verify that the thumbnail is 160x160 or smaller */
		if( ed->size > 12000 )
		{
			imsrc = image_new_from_jpeg(NULL, 0, ed->data, ed->size, 1, ROTATE_NONE);
			if( imsrc )
			{
 				if( (imsrc->width <= 160) && (imsrc->height <= 160) )
					thumb = 1;
				image_free(imsrc);
			}
		}
		else
			thumb = 1;
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb);

	exif_data_unref(ed);

no_exifdata:
	/* If SOF parsing fails, then fall through to reading the JPEG data with libjpeg to get the resolution */
	if( image_get_jpeg_resolution(path, &width, &height) != 0 || !width || !height )
	{
		infile = fopen(path, "r");
		if( infile )
		{
			cinfo.err = jpeg_std_error(&jerr);
			jerr.error_exit = libjpeg_error_handler;
			jpeg_create_decompress(&cinfo);
			if( setjmp(setjmp_buffer) )
				goto error;
			jpeg_stdio_src(&cinfo, infile);
			jpeg_read_header(&cinfo, TRUE);
			jpeg_start_decompress(&cinfo);
			width = cinfo.output_width;
			height = cinfo.output_height;
			error:
			jpeg_destroy_decompress(&cinfo);
			fclose(infile);
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height);

	if( !width || !height )
	{
		free_metadata(&m, free_flags);
		return 0;
	}
	if( width <= 640 && height <= 480 )
		m.dlna_pn = strdup("JPEG_SM");
	else if( width <= 1024 && height <= 768 )
		m.dlna_pn = strdup("JPEG_MED");
	else if( (width <= 4096 && height <= 4096) || !GETFLAG(DLNA_STRICT_MASK) )
		m.dlna_pn = strdup("JPEG_LRG");
	xasprintf(&m.resolution, "%dx%d", width, height);

	ret = sql_exec(db, "INSERT into DETAILS"
	                   " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION,"
	                    " ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) "
	                   "VALUES"
	                   " (%Q, '%q', %lld, %lld, %Q, %Q, %u, %d, %Q, %Q, %Q);",
	                   path, name, (long long)file.st_size, (long long)file.st_mtime, m.date,
	                   m.resolution, m.rotation, thumb, m.creator, m.dlna_pn, m.mime);
	if( ret != SQLITE_OK )
	{
		DPRINTF(E_ERROR, L_METADATA, "Error inserting details for '%s'!\n", path);
		ret = 0;
	}
	else
	{
		ret = sqlite3_last_insert_rowid(db);
	}
	free_metadata(&m, free_flags);

	return ret;
}
std::optional<ImageData2D> JpegImporter::doImage2D(UnsignedInt) {
    /* Initialize structures */
    jpeg_decompress_struct file;
    JSAMPARRAY rows = nullptr;
    unsigned char* data = nullptr;

    /* Fugly error handling stuff */
    /** @todo Get rid of this crap */
    struct ErrorManager {
        jpeg_error_mgr jpegErrorManager;
        std::jmp_buf setjmpBuffer;
    } errorManager;
    file.err = jpeg_std_error(&errorManager.jpegErrorManager);
    errorManager.jpegErrorManager.error_exit = [](j_common_ptr info) {
        info->err->output_message(info);
        std::longjmp(reinterpret_cast<ErrorManager*>(info->err)->setjmpBuffer, 1);
    };
    if(setjmp(errorManager.setjmpBuffer)) {
        Error() << "Trade::JpegImporter::image2D(): error while reading JPEG file";

        jpeg_destroy_decompress(&file);
        delete[] rows;
        delete[] data;
        return std::nullopt;
    }

    /* Open file */
    jpeg_create_decompress(&file);
    jpeg_mem_src(&file, _in.begin(), _in.size());

    /* Read file header, start decompression */
    jpeg_read_header(&file, true);
    jpeg_start_decompress(&file);

    /* Image size and type */
    const Vector2i size(file.output_width, file.output_height);
    static_assert(BITS_IN_JSAMPLE == 8, "Only 8-bit JPEG is supported");
    constexpr const ImageType type = ImageType::UnsignedByte;

    /* Image format */
    ImageFormat format;
    switch(file.out_color_space) {
        case JCS_GRAYSCALE:
            CORRADE_INTERNAL_ASSERT(file.out_color_components == 1);
            #ifdef MAGNUM_TARGET_GLES
            format = Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ?
                ImageFormat::Red : ImageFormat::Luminance;
            #else
            format = ImageFormat::Red;
            #endif
            break;
        case JCS_RGB:
            CORRADE_INTERNAL_ASSERT(file.out_color_components == 3);
            format = ImageFormat::RGB;
            break;

        /** @todo RGBA (only in libjpeg-turbo and probably ignored) */

        default:
            Error() << "Trade::JpegImporter::image2D(): unsupported color space" << file.out_color_space;
    }

    /* Initialize data array */
    data = new unsigned char[size.product()*file.out_color_components*BITS_IN_JSAMPLE/8];

    /* Read image row by row */
    rows = new JSAMPROW[size.y()];
    const Int stride = size.x()*file.out_color_components*BITS_IN_JSAMPLE/8;
    for(Int i = 0; i != size.y(); ++i)
        rows[i] = data + (size.y() - i - 1)*stride;
    while(file.output_scanline < file.output_height)
        jpeg_read_scanlines(&file, rows+file.output_scanline, file.output_height-file.output_scanline);
    delete[] rows;
    rows = nullptr;

    /* Cleanup */
    jpeg_finish_decompress(&file);
    jpeg_destroy_decompress(&file);

    return Trade::ImageData2D(format, type, size, data);
}
Exemplo n.º 27
0
/*
  Function: gdImageCreateFromJpegCtxEx

  See <gdImageCreateFromJpeg>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	jmpbuf_wrapper jmpbufw;
	/* volatile so we can gdFree them after longjmp */
	volatile JSAMPROW row = 0;
	volatile gdImagePtr im = 0;
	JSAMPROW rowptr[1];
	JDIMENSION i, j;
	int retval;
	JDIMENSION nrows;
	int channels = 3;
	int inverted = 0;

#ifdef JPEG_DEBUG
	gd_error_ex(GD_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
	gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
	gd_error_ex(GD_DEBUG, "sizeof: %d\n", sizeof(struct jpeg_decompress_struct));
#endif

	memset(&cinfo, 0, sizeof(cinfo));
	memset(&jerr, 0, sizeof(jerr));

	jmpbufw.ignore_warning = ignore_warning;

	cinfo.err = jpeg_std_error(&jerr);
	cinfo.client_data = &jmpbufw;

	cinfo.err->emit_message = jpeg_emit_message;

	if(setjmp(jmpbufw.jmpbuf) != 0) {
		/* we're here courtesy of longjmp */
		if(row) {
			gdFree(row);
		}
		if(im) {
			gdImageDestroy(im);
		}
		return 0;
	}

	cinfo.err->error_exit = fatal_jpeg_error;

	jpeg_create_decompress(&cinfo);

	jpeg_gdIOCtx_src(&cinfo, infile);

	/* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK
	 * files with inverted components.
	 */
	jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256);

	retval = jpeg_read_header(&cinfo, TRUE);
	if(retval != JPEG_HEADER_OK) {
		gd_error("gd-jpeg: warning: jpeg_read_header returns"
		         " %d, expected %d\n", retval, JPEG_HEADER_OK);
	}

	if(cinfo.image_height > INT_MAX) {
		gd_error("gd-jpeg: warning: JPEG image height (%u) is"
		         " greater than INT_MAX (%d) (and thus greater than"
		         " gd can handle)", cinfo.image_height, INT_MAX);
	}

	if(cinfo.image_width > INT_MAX) {
		gd_error("gd-jpeg: warning: JPEG image width (%u) is"
		         " greater than INT_MAX (%d) (and thus greater than"
		         " gd can handle)\n", cinfo.image_width, INT_MAX);
	}

	im = gdImageCreateTrueColor((int)cinfo.image_width, (int)cinfo.image_height);
	if(im == 0) {
		gd_error("gd-jpeg error: cannot allocate gdImage struct\n");
		goto error;
	}

	/* check if the resolution is specified */
	switch (cinfo.density_unit) {
	case 1:
		im->res_x = cinfo.X_density;
		im->res_y = cinfo.Y_density;
		break;
	case 2:
		im->res_x = DPCM2DPI(cinfo.X_density);
		im->res_y = DPCM2DPI(cinfo.Y_density);
		break;
	}

	/* 2.0.22: very basic support for reading CMYK colorspace files. Nice for
	 * thumbnails but there's no support for fussy adjustment of the
	 * assumed properties of inks and paper.
	 */
	if((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) {
		cinfo.out_color_space = JCS_CMYK;
	} else {
		cinfo.out_color_space = JCS_RGB;
	}

	if(jpeg_start_decompress(&cinfo) != TRUE) {
		gd_error("gd-jpeg: warning: jpeg_start_decompress"
		        " reports suspended data source\n");
	}

#ifdef JPEG_DEBUG
	gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG image information:");
	if(cinfo.saw_JFIF_marker) {
		gd_error_ex(GD_DEBUG, " JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version);
	} else if(cinfo.saw_Adobe_marker) {
		gd_error_ex(GD_DEBUG, " Adobe format");
	} else {
		gd_error_ex(GD_DEBUG, " UNKNOWN format");
	}

	gd_error_ex(GD_DEBUG, " %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
		    cinfo.image_height, cinfo.output_width,
		    cinfo.output_height, cinfo.data_precision
		);
	gd_error_ex(GD_DEBUG, " %s", (cinfo.progressive_mode ? "progressive" : "baseline"));
	gd_error_ex(GD_DEBUG, " image, %d quantized colors, ", cinfo.actual_number_of_colors);

	switch(cinfo.jpeg_color_space) {
	case JCS_GRAYSCALE:
		gd_error_ex(GD_DEBUG, "grayscale");
		break;

	case JCS_RGB:
		gd_error_ex(GD_DEBUG, "RGB");
		break;

	case JCS_YCbCr:
		gd_error_ex(GD_DEBUG, "YCbCr (a.k.a. YUV)");
		break;

	case JCS_CMYK:
		gd_error_ex(GD_DEBUG, "CMYK");
		break;

	case JCS_YCCK:
		gd_error_ex(GD_DEBUG, "YCbCrK");
		break;

	default:
		gd_error_ex(GD_DEBUG, "UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space);
		break;
	}

	gd_error_ex(GD_DEBUG, " colorspace\n");
	fflush(stdout);
#endif /* JPEG_DEBUG */

	/* REMOVED by TBB 2/12/01. This field of the structure is
	 * documented as private, and sure enough it's gone in the
	 * latest libjpeg, replaced by something else. Unfortunately
	 * there is still no right way to find out if the file was
	 * progressive or not; just declare your intent before you
	 * write one by calling gdImageInterlace(im, 1) yourself.
	 * After all, we're not really supposed to rework JPEGs and
	 * write them out again anyway. Lossy compression, remember? */
#if 0
	gdImageInterlace (im, cinfo.progressive_mode != 0);
#endif
	if(cinfo.out_color_space == JCS_RGB) {
		if(cinfo.output_components != 3) {
			gd_error("gd-jpeg: error: JPEG color quantization"
			         " request resulted in output_components == %d"
			         " (expected 3 for RGB)\n", cinfo.output_components);
			goto error;
		}
		channels = 3;
	} else if(cinfo.out_color_space == JCS_CMYK) {
		jpeg_saved_marker_ptr marker;
		if(cinfo.output_components != 4) {
			gd_error("gd-jpeg: error: JPEG color quantization"
			         " request resulted in output_components == %d"
			         " (expected 4 for CMYK)\n", cinfo.output_components);
			goto error;
		}
		channels = 4;

		marker = cinfo.marker_list;
		while(marker) {
			if(	(marker->marker == (JPEG_APP0 + 14)) &&
			        (marker->data_length >= 12) &&
			        (!strncmp((const char *)marker->data, "Adobe", 5))) {
				inverted = 1;
				break;
			}
			marker = marker->next;
		}
	} else {
		gd_error("gd-jpeg: error: unexpected colorspace\n");
		goto error;
	}
#if BITS_IN_JSAMPLE == 12
	gd_error_ex(GD_ERROR,
		    "gd-jpeg: error: jpeg library was compiled for 12-bit\n"
		    "precision. This is mostly useless, because JPEGs on the web are\n"
		    "8-bit and such versions of the jpeg library won't read or write\n"
		    "them. GD doesn't support these unusual images. Edit your\n"
		    "jmorecfg.h file to specify the correct precision and completely\n"
		    "'make clean' and 'make install' libjpeg again. Sorry.\n");
	goto error;
#endif /* BITS_IN_JSAMPLE == 12 */

	row = gdCalloc(cinfo.output_width *channels, sizeof(JSAMPLE));
	if(row == 0) {
		gd_error("gd-jpeg: error: unable to allocate row for"
		         " JPEG scanline: gdCalloc returns NULL\n");
		goto error;
	}
	rowptr[0] = row;
	if(cinfo.out_color_space == JCS_CMYK) {
		for(i = 0; i < cinfo.output_height; i++) {
			register JSAMPROW currow = row;
			register int *tpix = im->tpixels[i];
			nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
			if(nrows != 1) {
				gd_error("gd-jpeg: error: jpeg_read_scanlines"
				         " returns %u, expected 1\n", nrows);
				goto error;
			}
			for(j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) {
				*tpix = CMYKToRGB(currow[0], currow[1], currow[2], currow[3], inverted);
			}
		}
	} else {
		for(i = 0; i < cinfo.output_height; i++) {
			register JSAMPROW currow = row;
			register int *tpix = im->tpixels[i];
			nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
			if(nrows != 1) {
				gd_error("gd-jpeg: error: jpeg_read_scanlines"
				         " returns %u, expected 1\n", nrows);
				goto error;
			}
			for(j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) {
				*tpix = gdTrueColor(currow[0], currow[1], currow[2]);
			}
		}
	}

	if(jpeg_finish_decompress (&cinfo) != TRUE) {
		gd_error("gd-jpeg: warning: jpeg_finish_decompress"
		         " reports suspended data source\n");
	}
	/* TBB 2.0.29: we should do our best to read whatever we can read, and a
	 * warning is a warning. A fatal error on warnings doesn't make sense. */
#if 0
	/* This was originally added by Truxton Fulton */
	if (cinfo.err->num_warnings > 0)
		goto error;
#endif

	jpeg_destroy_decompress(&cinfo);
	gdFree(row);
	return im;

error:
	jpeg_destroy_decompress(&cinfo);

	if(row) {
		gdFree(row);
	}
	if(im) {
		gdImageDestroy(im);
	}

	return 0;
}
Exemplo n.º 28
0
image_t* image_load_jpg(image_t* x, stream_t* stream)
{
  image_t* im;

  TRACE1 ("loading jpeg file");

  if (!stream) {
    im = NULL;
  } else {
    int load;
    im = image_instantiate_toplevel (x);

    struct jpeg_decompress_struct cinfo;
    myerror_mgr errmgr;

    errmgr.im = im;
    errmgr.image_is_owned_p = (im != x);

    if (setjmp (errmgr.env)) {
	    jpeg_destroy_decompress(&cinfo);

	// coming back from an error
	return NULL;
    }

    /* insert here useless error test */
    /* jpeg object initialisation */
    jpeg_create_decompress (&cinfo);

    /* specify data source */
    jpeg_stream_src (&cinfo, stream);

    /* standard error */
    cinfo.err               = jpeg_std_error (&errmgr.super);
    errmgr.super.error_exit = image_load_jpeg_error_exit;

    if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) {
	    return NULL;
    }

    if (jpeg_start_decompress(&cinfo) < 0) {
	    return NULL;
    }

    if (!cinfo.output_width || !cinfo.output_height) {
	    WARNING1("null size image.");
	    return NULL;
    }

    image_new(im,
	      cinfo.output_width,
	      cinfo.output_height,
	      cinfo.output_width);

    switch (cinfo.output_components) {
    case 1: /* GRAY */
	load = 1;
	break;
    case 3: // RGB
	load = 1;
	break;
    default:
	/* don't know how to load that */
	image_destroy (im);
	if(im != x) {
		image_retire (im);
	}
	im = NULL;

	load = 0;
    }

    if (load) {
	JSAMPARRAY scanline_buf;

	scanline_buf = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE,
		 cinfo.output_width *
		 cinfo.output_components,
		 cinfo.rec_outbuf_height);

	while (cinfo.output_scanline < cinfo.output_height) {
	    int n;

	    uint32_t* dest = im->pixels + im->pitch * cinfo.output_scanline;

	    n = jpeg_read_scanlines(&cinfo,
				    scanline_buf,
				    cinfo.rec_outbuf_height);

	    int s;
	    for (s = 0; s < n; s++) {
		    unsigned char* scanline = scanline_buf [s];

		    /* copy to image */
		    int i;
		    for (i = 0; i < im->width; i++) {
			    if(cinfo.output_components == 1) {
				    dest[i] = 0xff000000 |
					    (scanline[i] << 16) |
					    (scanline[i] << 8) |
					    (scanline[i]);
			    } else if(cinfo.output_components == 3) {
#if (BYTE_ORDER == LITTLE_ENDIAN && defined (PIXEL_RGBA8888)) ||	\
	(BYTE_ORDER == BIG_ENDIAN && defined (PIXEL_BGRA8888))
				    dest[i] =
					    0xff000000 |
					    (scanline [3*i + 0] << 16) |
					    (scanline [3*i + 1] << 8) |
					    (scanline [3*i + 2] << 0);
#else
				    /*dest[i] = 0xff000000 | //alpha
					    (scanline [3*i + 2] << 0) |
					    (scanline [3*i + 1] << 8) |
					    (scanline [3*i + 2] << 16);
				    */
				    dest[i] = 0xff000000 | // alpha
					    (scanline [3 * i + 0] << 0) | // r
					    (scanline [3 * i + 1] << 8) | // g
					    (scanline [3 * i + 2] << 16); // b

#endif
			    }
		    }
		    dest += im->pitch;
	    }
	}
    }

    jpeg_finish_decompress(&cinfo);

  }

    return im;
}
Exemplo n.º 29
0
imgdata loadJpeg( const char* filename){
    unsigned char a,r,g,b;
    int img_width, img_height;

    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    FILE *file;
    JSAMPARRAY pJpegBuffer;
    int row_stride;

    std::string image_name(filename);
    file = fopen(image_name.c_str(), "rb");
    if( file == NULL){
        std::string msg("Error opening ");
        throw std::runtime_error(msg + image_name);
    }
    printf("Loading in files %s\n", image_name.c_str());

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, file);
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);
    img_width  = cinfo.image_width;
    img_height = cinfo.image_height;
    printf("img_width %d img_height %d\n", img_width, img_height);

    unsigned char *img_data = new unsigned char [4 * img_height * img_width];
    unsigned char *pTest = img_data;
    if(!img_data){
        std::string msg("NO MEM FOR JPEG CONVERT!\n");
        throw std::runtime_error(msg);
    }

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

    while( cinfo.output_scanline < cinfo.output_height){
        jpeg_read_scanlines(&cinfo, pJpegBuffer, 1);
        for( int x=0; x<img_width; x++){
            a = 0;
            r = pJpegBuffer[0][cinfo.output_components*x];
            if( cinfo.output_components > 2){
                g = pJpegBuffer[0][cinfo.output_components*x+1];
                b = pJpegBuffer[0][cinfo.output_components*x+2];
            }else{
                g = r;
                b = r;
            }
            //printf( "r %c g %c b %c\n", r,g,b);
            *(img_data++) = r;
            *(img_data++) = g;
            *(img_data++) = b;
            *(img_data++) = a;
        }
    }
    fclose(file);
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    imgdata retval;
    retval.height = img_height;
    retval.width = img_width;
    retval.data = pTest;

    return retval;
}
Exemplo n.º 30
0
jpeg_comp_dct_t *libjpeg_get_dct_data(const char *filepath)
{
	int ic, ret;
	xyi_t ib;
	uint8_t *filedata;
	size_t filedata_size;
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	jvirt_barray_ptr *coefs;
	jpeg_comp_dct_t *out=NULL;
	JBLOCKARRAY dct;
	jpeg_component_info *compinf;
	
	filedata = load_raw_file(filepath, &filedata_size);
	if (filedata==NULL)
		return NULL;
	
	// allocate and initialize JPEG decompression object
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);

	jpeg_mem_src(&cinfo, filedata, filedata_size);
	//jpeg_stdio_src(&cinfo, file);		// specify file

	ret = jpeg_read_header(&cinfo, TRUE);	// read file header
	if (ret != 1)
		fprintf_rl(stderr, "File '%s' cannot be read by jpeg_read_header()\n", filepath);
	else
	{
		coefs = jpeg_read_coefficients(&cinfo);	// read all the coefs (DCT, quantisation table etc)

		if (coefs)
		{
			out = calloc(3, sizeof(jpeg_comp_dct_t));

			// copy every DCT block and the quantisation table for every component
			for (ic=0; ic<3; ic++)
			{
				compinf = &cinfo.comp_info[ic];
				out[ic].image_dim = xyi(cinfo.image_width, cinfo.image_height);
				out[ic].block_dim = xyi(compinf->width_in_blocks, compinf->height_in_blocks);
				dct = (cinfo.mem->access_virt_barray) ((j_common_ptr) (&cinfo), coefs[ic], 0, compinf->v_samp_factor, FALSE);

				memcpy(out[ic].quant, compinf->quant_table->quantval, DCTSIZE2 * sizeof(uint16_t));	// copy quantisation table

				// copy DCT blocks
				out[ic].dct_block = calloc(mul_x_by_y_xyi(out[ic].block_dim), sizeof(int16_t *));
				for (ib.y=0; ib.y < out[ic].block_dim.y; ib.y++)
					for (ib.x=0; ib.x < out[ic].block_dim.x; ib.x++)
					{
						out[ic].dct_block[ib.y * out[ic].block_dim.x + ib.x] = calloc(DCTSIZE2, sizeof(int16_t));
						memcpy(out[ic].dct_block[ib.y * out[ic].block_dim.x + ib.x], dct[ib.y][ib.x], DCTSIZE2 * sizeof(int16_t));
					}
			}
		}
	}

	// free the libjpeg stuff
	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);

	free(filedata);

	return out;
}