コード例 #1
0
ファイル: jpeg.c プロジェクト: learn-OS/ygloo-ymagine
static int
bitmap_decode(struct jpeg_decompress_struct *cinfo, Vbitmap *vbitmap,
              YmagineFormatOptions *options)
{
  int nlines = -1;

  cinfo->client_data = (void*) vbitmap;
  
  if (prepareDecompressor(cinfo, options) != YMAGINE_OK) {
    return nlines;
  }

  /* Intercept APP1 markers for PhotoSphere parsing */
  jpeg_set_marker_processor(cinfo, JPEG_APP0 + 1, APP1_handler);
  
  if (startDecompressor(cinfo, VbitmapColormode(vbitmap)) != YMAGINE_OK) {
    return nlines;
  }
  
  YmagineFormatOptions_invokeCallback(options, YMAGINE_IMAGEFORMAT_JPEG,
                                      cinfo->image_width, cinfo->image_height);

#if YMAGINE_DEBUG_JPEG
  ALOGD("bitmap_decode: in=%dx%d bm=%dx%d max=%dx%d",
        cinfo->image_width, cinfo->image_height,
        VbitmapWidth(vbitmap), VbitmapHeight(vbitmap),
        options->maxwidth, options->maxheight);
#endif
  
  nlines = decompress_jpeg(cinfo, NULL, JCOPYOPT_NONE,
                           vbitmap, options);
  
  return nlines;
}
コード例 #2
0
ファイル: jpegio.c プロジェクト: MaTriXy/tess-two
/*
 *  fgetJpegComment()
 *
 *      Input:  fp (file stream opened for read)
 *              &comment (<return> comment)
 *      Return: 0 if OK; 1 on error
 *
 *  Notes:
 *      (1) Side-effect: this rewinds the stream.
 */
l_int32
fgetJpegComment(FILE      *fp,
                l_uint8  **pcomment)
{
struct jpeg_decompress_struct  cinfo;
struct jpeg_error_mgr          jerr;
struct callback_data           cb_data;  /* contains local jmp_buf */

    PROCNAME("fgetJpegComment");

    if (!pcomment)
        return ERROR_INT("&comment not defined", procName, 1);
    *pcomment = NULL;
    if (!fp)
        return ERROR_INT("stream not opened", procName, 1);

    rewind(fp);

        /* Modify the jpeg error handling to catch fatal errors  */
    cinfo.err = jpeg_std_error(&jerr);
    jerr.error_exit = jpeg_error_catch_all_2;
    cb_data.comment = NULL;
    cinfo.client_data = (void *)&cb_data;
    if (setjmp(cb_data.jmpbuf)) {
        LEPT_FREE(cb_data.comment);
        return ERROR_INT("internal jpeg error", procName, 1);
    }

        /* Initialize the jpeg structs for reading the header */
    jpeg_create_decompress(&cinfo);
    jpeg_set_marker_processor(&cinfo, JPEG_COM, jpeg_comment_callback);
    jpeg_stdio_src(&cinfo, fp);
    jpeg_read_header(&cinfo, TRUE);

        /* Save the result */
    *pcomment = cb_data.comment;
    jpeg_destroy_decompress(&cinfo);
    rewind(fp);
    return 0;
}
コード例 #3
0
int
main (int argc, char **argv)
{
  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;

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

  /* 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) &cinfo, &progress);
#endif

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

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

  /* 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) &cinfo);
#endif

  /* All done. */
  exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
  return 0;			/* suppress no-return-value warnings */
}
コード例 #4
0
ファイル: common.c プロジェクト: CplusHua/stegdetect
int
jpg_open(char *filename)
{
	char outbuf[1024];
	int i;
	struct my_error_mgr jerr;
	jpeg_component_info *compptr;
	FILE *fin;

	comments_init();
	jpg_markers = 0;
	
	if ((fin = fopen(filename, "r")) == NULL) {
		int error = errno;

		fprintf(stderr, "%s : error: %s\n",
			filename, strerror(error));
		return (-1);
	}

	jinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	if (stego_eoi_cb != NULL)
		jerr.pub.emit_message = my_error_emit;
	/* Establish the setjmp return context for my_error_exit to use. */
	if (setjmp(jerr.setjmp_buffer)) {
		/* Always display the message. */
		(*jinfo.err->format_message) ((j_common_ptr)&jinfo, outbuf);

		fprintf(stderr, "%s : error: %s\n", filename, outbuf);

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

		fclose(fin);
		return (-1);
	}
	jpeg_create_decompress(&jinfo);
	jpeg_set_marker_processor(&jinfo, JPEG_COM, comment_handler);
	for (i = 1; i < 16; i++)
		jpeg_set_marker_processor(&jinfo, JPEG_APP0+i, marker_handler);
	jpeg_stdio_src(&jinfo, fin);
	jpeg_read_header(&jinfo, TRUE);

	/* jinfo.quantize_colors = TRUE; */
	dctcoeff = (njvirt_barray_ptr *)jpeg_read_coefficients(&jinfo);

	fclose(fin);

	if (dctcoeff == NULL) {
		fprintf(stderr, "%s : error: can not get coefficients\n",
		    filename);
		goto out;
	}

	if (jinfo.out_color_space != JCS_RGB) {
		fprintf(stderr, "%s : error: is not a RGB image\n", filename);
		goto out;
	}
 
	i = jinfo.num_components;
	if (i != 3) {
		fprintf(stderr,
			"%s : error: wrong number of color components: %d\n",
			filename, i);
		goto out;
	}
	
	for(i = 0; i < 3; i++) {
		compptr = jinfo.cur_comp_info[i];
		/*
		fprintf(stderr,
			"input_iMCU_row: %d, v_samp_factor: %d\n",
			jinfo.input_iMCU_row * compptr->v_samp_factor,
			(JDIMENSION) compptr->v_samp_factor);

		fprintf(stderr, "hib: %d, wib: %d\n",
			jinfo.comp_info[i].height_in_blocks,
			jinfo.comp_info[i].width_in_blocks);
		*/

		wib[i] = jinfo.comp_info[i].width_in_blocks;
		hib[i] = jinfo.comp_info[i].height_in_blocks;
		dctcompbuf[i] = dctcoeff[i]->mem_buffer;
	}

	return (0);
out:
	jpg_destroy();

	return (-1);
}
コード例 #5
0
static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags)
{
    JSAMPARRAY row_pointer;
    JSAMPLE * buffer = NULL;
    int row_stride;
    int x, y, depth, r, g, b, k;
    struct ImBuf * ibuf = NULL;
    uchar * rect;
    jpeg_saved_marker_ptr marker;
    char *str, *key, *value;

    /* install own app1 handler */
    ibuf_ftype = 0;
    jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
    cinfo->dct_method = JDCT_FLOAT;
    jpeg_save_markers(cinfo, JPEG_COM, 0xffff);

    if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) {
        x = cinfo->image_width;
        y = cinfo->image_height;
        depth = cinfo->num_components;

        if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK;

        jpeg_start_decompress(cinfo);

        if (ibuf_ftype == 0) {
            ibuf_ftype = JPG_STD;
            if (cinfo->max_v_samp_factor == 1) {
                if (cinfo->max_h_samp_factor == 1) ibuf_ftype = JPG_MAX;
                else ibuf_ftype = JPG_VID;
            }
        }

        if (flags & IB_test) {
            jpeg_abort_decompress(cinfo);
            ibuf = IMB_allocImBuf(x, y, 8 * depth, 0);
        }
        else if ((ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect)) == NULL) {
            jpeg_abort_decompress(cinfo);
        }
        else {
            row_stride = cinfo->output_width * depth;

            row_pointer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1);

            for (y = ibuf->y - 1; y >= 0; y--) {
                jpeg_read_scanlines(cinfo, row_pointer, 1);
                rect = (uchar *) (ibuf->rect + y * ibuf->x);
                buffer = row_pointer[0];

                switch(depth) {
                case 1:
                    for (x=ibuf->x; x >0; x--) {
                        rect[3] = 255;
                        rect[0] = rect[1] = rect[2] = *buffer++;
                        rect += 4;
                    }
                    break;
                case 3:
                    for (x=ibuf->x; x >0; x--) {
                        rect[3] = 255;
                        rect[0] = *buffer++;
                        rect[1] = *buffer++;
                        rect[2] = *buffer++;
                        rect += 4;
                    }
                    break;
                case 4:
                    for (x=ibuf->x; x >0; x--) {
                        r = *buffer++;
                        g = *buffer++;
                        b = *buffer++;
                        k = *buffer++;

                        k = 255 - k;
                        r -= k;
                        if (r & 0xffffff00) {
                            if (r < 0) r = 0;
                            else r = 255;
                        }
                        g -= k;
                        if (g & 0xffffff00) {
                            if (g < 0) g = 0;
                            else g = 255;
                        }
                        b -= k;
                        if (b & 0xffffff00) {
                            if (b < 0) b = 0;
                            else b = 255;
                        }

                        rect[3] = 255 - k;
                        rect[2] = b;
                        rect[1] = g;
                        rect[0] = r;
                        rect += 4;
                    }
                }
            }

            marker= cinfo->marker_list;
            while(marker) {
                if(marker->marker != JPEG_COM)
                    goto next_stamp_marker;

                /*
                 * Because JPEG format don't support the
                 * pair "key/value" like PNG, we store the
                 * stampinfo in a single "encode" string:
                 *	"Blender:key:value"
                 *
                 * That is why we need split it to the
                 * common key/value here.
                 */
                if(strncmp((char *) marker->data, "Blender", 7)) {
                    /*
                     * Maybe the file have text that
                     * we don't know "what it's", in that
                     * case we keep the text (with a
                     * key "None").
                     * This is only for don't "lose"
                     * the information when we write
                     * it back to disk.
                     */
                    IMB_metadata_add_field(ibuf, "None", (char *) marker->data);
                    ibuf->flags |= IB_metadata;
                    goto next_stamp_marker;
                }

                str = BLI_strdup ((char *) marker->data);
                key = strchr (str, ':');
                /*
                 * A little paranoid, but the file maybe
                 * is broken... and a "extra" check is better
                 * that a segfaul ;)
                 */
                if (!key) {
                    MEM_freeN(str);
                    goto next_stamp_marker;
                }

                key++;
                value = strchr (key, ':');
                if (!value) {
                    MEM_freeN(str);
                    goto next_stamp_marker;
                }

                *value = '\0'; /* need finish the key string */
                value++;
                IMB_metadata_add_field(ibuf, key, value);
                ibuf->flags |= IB_metadata;
                MEM_freeN(str);
next_stamp_marker:
                marker= marker->next;
            }

            jpeg_finish_decompress(cinfo);
        }

        jpeg_destroy((j_common_ptr) cinfo);
        if(ibuf) {
            ibuf->ftype = ibuf_ftype;
            ibuf->profile = IB_PROFILE_SRGB;
        }
    }

    return(ibuf);
}
コード例 #6
0
ファイル: djpeg.c プロジェクト: LonghronShen/krkrz
process_one_file (int argc, char **argv, int old_file_index)
{
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  char *infilename;
  char workfilename[PATH_MAX];
  const char *default_extension = NULL;
#ifdef PROGRESS_REPORT
  struct cdjpeg_progress_mgr progress;
#endif
  int file_index;
  djpeg_dest_ptr dest_mgr = NULL;
  FILE * input_file = NULL;
  FILE * output_file = NULL;
  JDIMENSION num_scanlines;

  /* 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 next file name.
   * 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, old_file_index, FALSE);
  if (file_index >= argc) {
    fprintf(stderr, "%s: missing input file name\n", progname);
    usage();
  }

  /* Open the input file. */
  infilename = argv[file_index];
  if ((input_file = fopen(infilename, READ_BINARY)) == NULL) {
    fprintf(stderr, "%s: can't open %s\n", progname, infilename);
    goto fail;
  }

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

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

  /* 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, old_file_index, 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);
    default_extension = ".bmp";
    break;
  case FMT_OS2:
    dest_mgr = jinit_write_bmp(&cinfo, TRUE);
    default_extension = ".bmp";
    break;
#endif
#ifdef GIF_SUPPORTED
  case FMT_GIF:
    dest_mgr = jinit_write_gif(&cinfo);
    default_extension = ".gif";
    break;
#endif
#ifdef PPM_SUPPORTED
  case FMT_PPM:
    dest_mgr = jinit_write_ppm(&cinfo);
    default_extension = ".ppm";
    break;
#endif
#ifdef RLE_SUPPORTED
  case FMT_RLE:
    dest_mgr = jinit_write_rle(&cinfo);
    default_extension = ".rle";
    break;
#endif
#ifdef TARGA_SUPPORTED
  case FMT_TARGA:
    dest_mgr = jinit_write_targa(&cinfo);
    default_extension = ".tga";
    break;
#endif
  default:
    ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT);
    break;
  }

  /* If user didn't supply -outfile switch, select output file name. */
  if (outfilename == NULL) {
    int i;

    outfilename = workfilename;
    /* Make outfilename be infilename with appropriate extension */
    strcpy(outfilename, infilename);
    for (i = strlen(outfilename)-1; i >= 0; i--) {
      switch (outfilename[i]) {
      case ':':
      case '/':
      case '\\':
	i = 0;			/* stop scanning */
	break;
      case '.':
	outfilename[i] = '\0';	/* lop off existing extension */
	i = 0;			/* stop scanning */
	break;
      default:
	break;			/* keep scanning */
      }
    }
    strcat(outfilename, default_extension);
  }

  fprintf(stderr, "Decompressing %s => %s\n", infilename, outfilename);
#ifndef NO_OVERWRITE_CHECK
  if (! is_write_ok(outfilename))
    goto fail;
#endif

  /* Open the output file. */
  if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
    fprintf(stderr, "%s: can't create %s\n", progname, outfilename);
    goto fail;
  }
  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);

  /* Clean up and exit */
fail:
  jpeg_destroy_decompress(&cinfo);

  if (input_file != NULL) fclose(input_file);
  if (output_file != NULL) fclose(output_file);

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

  /* Disable signal catcher. */
#ifdef NEED_SIGNAL_CATCHER
  enable_signal_catcher((j_common_ptr) NULL);
#endif

  return file_index;
}
コード例 #7
0
ファイル: cmp.c プロジェクト: LucidOne/Rovio
int djpeg (char *inbuf,int inbuflen,unsigned char **ppout)
{
  struct jpeg_decompress_struct cinfo ;
  struct jpeg_error_mgr jerr ;

  djpeg_dest_ptr dest_mgr = NULL;
  JDIMENSION num_scanlines;

  if (ppout == NULL) return -1;
  *ppout = NULL;

  /* Initialize the JPEG decompression object with default error handling. */
  cinfo.err = jpeg_std_error(&jerr);
  cinfo.err->error_exit = My_Error_Exit;

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


  set_cinfo(&cinfo);

  Jpeg_Memory_Src(&cinfo, inbuf, inbuflen);

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

  /* Adjust default decompression parameters by re-parsing the options */

  set_cinfo(&cinfo);
  /* Initialize the output module now to let it override any crucial
   * option settings (for instance, GIF wants to force color quantization).
   */
  dest_mgr = jinit_write_bmp(&cinfo, FALSE);

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


  /* 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.
   */
  put_gray_to_buff(&cinfo,dest_mgr,ppout);	 //toview
  (void) jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);


  return 0;
}
コード例 #8
0
/*!
 *  pixReadStreamJpeg()
 *
 *      Input:  stream
 *              colormap flag (0 means return RGB image if color;
 *                             1 means create colormap and return 8 bpp
 *                               palette image if color)
 *              reduction (scaling factor: 1, 2, 4 or 8)
 *              &pnwarn (<optional return> number of warnings)
 *              hint: (a bitwise OR of L_HINT_* values); use 0 for no hints
 *      Return: pix, or null on error
 *
 *  Usage: see pixReadJpeg()
 */
PIX *
pixReadStreamJpeg(FILE     *fp,
                  l_int32   cmflag,
                  l_int32   reduction,
                  l_int32  *pnwarn,
                  l_int32   hint)
{
l_uint8                        cyan, yellow, magenta, black, white;
l_int32                        rval, gval, bval;
l_int32                        i, j, k;
l_int32                        w, h, wpl, spp, ncolors, cindex, ycck, cmyk;
l_uint32                      *data;
l_uint32                      *line, *ppixel;
JSAMPROW                       rowbuffer;
PIX                           *pix;
PIXCMAP                       *cmap;
struct jpeg_decompress_struct  cinfo;
struct jpeg_error_mgr          jerr;
l_uint8                       *comment = NULL;

    PROCNAME("pixReadStreamJpeg");

    if (!fp)
        return (PIX *)ERROR_PTR("fp not defined", procName, NULL);
    if (pnwarn)
        *pnwarn = 0;  /* init */
    if (cmflag != 0 && cmflag != 1)
        cmflag = 0;  /* default */
    if (reduction != 1 && reduction != 2 && reduction != 4 && reduction != 8)
        return (PIX *)ERROR_PTR("reduction not in {1,2,4,8}", procName, NULL);

    if (BITS_IN_JSAMPLE != 8)  /* set in jmorecfg.h */
        return (PIX *)ERROR_PTR("BITS_IN_JSAMPLE != 8", procName, NULL);

    rewind(fp);

    pix = NULL;  /* init */
    if (setjmp(jpeg_jmpbuf)) {
        pixDestroy(&pix);
        FREE(rowbuffer);
        return (PIX *)ERROR_PTR("internal jpeg error", procName, NULL);
    }

    rowbuffer = NULL;
    cinfo.err = jpeg_std_error(&jerr);
    jerr.error_exit = jpeg_error_do_not_exit; /* catch error; do not exit! */

    jpeg_create_decompress(&cinfo);

    cinfo.client_data = &comment;
    jpeg_set_marker_processor(&cinfo, JPEG_COM, jpeg_comment_callback);
    jpeg_stdio_src(&cinfo, fp);
    jpeg_read_header(&cinfo, TRUE);
    cinfo.scale_denom = reduction;
    cinfo.scale_num = 1;
    if (hint & L_HINT_GRAY)
        cinfo.out_color_space = JCS_GRAYSCALE;
    jpeg_calc_output_dimensions(&cinfo);

        /* Allocate the image and a row buffer */
    spp = cinfo.out_color_components;
    w = cinfo.output_width;
    h = cinfo.output_height;
    ycck = (cinfo.jpeg_color_space == JCS_YCCK && spp == 4 && cmflag == 0);
    cmyk = (cinfo.jpeg_color_space == JCS_CMYK && spp == 4 && cmflag == 0);
    if (spp != 1 && spp != 3 && !ycck && !cmyk) {
        if (comment) FREE(comment);
        return (PIX *)ERROR_PTR("spp must be 1 or 3, or YCCK or CMYK",
                                procName, NULL);
    }
    if ((spp == 3 && cmflag == 0) || ycck || cmyk) {  /* rgb or 4 bpp color */
        rowbuffer = (JSAMPROW)CALLOC(sizeof(JSAMPLE), spp * w);
        pix = pixCreate(w, h, 32);
    }
    else {  /* 8 bpp gray or colormapped */
        rowbuffer = (JSAMPROW)CALLOC(sizeof(JSAMPLE), w);
        pix = pixCreate(w, h, 8);
    }
    if (!rowbuffer || !pix) {
        if (comment) FREE(comment);
	if (rowbuffer) FREE(rowbuffer);
	pixDestroy(&pix);
        return (PIX *)ERROR_PTR("rowbuffer or pix not made", procName, NULL);
    }

    if (comment) {
        pixSetText(pix, (char *)comment);
	FREE(comment);
    }

    if (spp == 1)  /* Grayscale or colormapped */
        jpeg_start_decompress(&cinfo);
    else  {        /* Color; spp == 3 or YCCK or CMYK */
        if (cmflag == 0) {   /* -- 24 bit color in 32 bit pix or YCCK/CMYK -- */
            cinfo.quantize_colors = FALSE;
            jpeg_start_decompress(&cinfo);
        }
        else {      /* Color quantize to 8 bits */
            cinfo.quantize_colors = TRUE;
            cinfo.desired_number_of_colors = 256;
            jpeg_start_decompress(&cinfo);

                /* Construct a pix cmap */
            cmap = pixcmapCreate(8);
            ncolors = cinfo.actual_number_of_colors;
            for (cindex = 0; cindex < ncolors; cindex++)
            {
                rval = cinfo.colormap[0][cindex];
                gval = cinfo.colormap[1][cindex];
                bval = cinfo.colormap[2][cindex];
                pixcmapAddColor(cmap, rval, gval, bval);
            }
            pixSetColormap(pix, cmap);
        }
    }
    wpl  = pixGetWpl(pix);
    data = pixGetData(pix);

        /* Decompress */
    if ((spp == 3 && cmflag == 0) || ycck || cmyk) {   /* -- 24 bit color -- */
        for (i = 0; i < h; i++) {
            if (jpeg_read_scanlines(&cinfo, &rowbuffer, (JDIMENSION)1) != 1)
                return (PIX *)ERROR_PTR("bad read scanline", procName, NULL);
            ppixel = data + i * wpl;
            if (spp == 3) {
                for (j = k = 0; j < w; j++) {
                    SET_DATA_BYTE(ppixel, COLOR_RED, rowbuffer[k++]);
                    SET_DATA_BYTE(ppixel, COLOR_GREEN, rowbuffer[k++]);
                    SET_DATA_BYTE(ppixel, COLOR_BLUE, rowbuffer[k++]);
                    ppixel++;
                }
            } else {
                    /* This is a conversion from CMYK -> RGB that ignores
                       color profiles, and is invoked when the image header
                       claims to be in CMYK or YCCK colorspace.  If in YCCK,
                       libjpeg may be doing YCCK -> CMYK under the hood.
                       To understand why the colors are inverted on read-in,
                       see the "Special color spaces" section of
                       "Using the IJG JPEG Library" by Thomas G. Lane.  */
                for (j = k = 0; j < w; j++) {
                    cyan = 255 - rowbuffer[k++];
                    magenta = 255 - rowbuffer[k++];
                    yellow = 255 - rowbuffer[k++];
                    white = rowbuffer[k++];
                    black = 255 - white;
                    rval = 255 - (cyan    * white) / 255 - black;
                    gval = 255 - (magenta * white) / 255 - black;
                    bval = 255 - (yellow  * white) / 255 - black;
                    rval = L_MIN(L_MAX(rval, 0), 255);
                    gval = L_MIN(L_MAX(gval, 0), 255);
                    bval = L_MIN(L_MAX(bval, 0), 255);
                    composeRGBPixel(rval, gval, bval, ppixel);
                    ppixel++;
                }
            }
        }
    }
    else {    /* 8 bpp grayscale or colormapped pix */
        for (i = 0; i < h; i++) {
            if (jpeg_read_scanlines(&cinfo, &rowbuffer, (JDIMENSION)1) != 1)
                return (PIX *)ERROR_PTR("bad read scanline", procName, NULL);
            line = data + i * wpl;
            for (j = 0; j < w; j++)
                SET_DATA_BYTE(line, j, rowbuffer[j]);
        }
    }

    if (pnwarn)
        *pnwarn = cinfo.err->num_warnings;

    switch (cinfo.density_unit)
    {
    case 1:  /* pixels per inch */
        pixSetXRes(pix, cinfo.X_density);
        pixSetYRes(pix, cinfo.Y_density);
        break;
    case 2:  /* pixels per centimeter */
        pixSetXRes(pix, (l_int32)((l_float32)cinfo.X_density * 2.54 + 0.5));
        pixSetYRes(pix, (l_int32)((l_float32)cinfo.Y_density * 2.54 + 0.5));
        break;
    default:   /* the pixel density may not be defined; ignore */
        break;
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    FREE(rowbuffer);

    return pix;
}
コード例 #9
0
ファイル: jpeg.c プロジェクト: bdancer/blender-for-vray
static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int flags)
{
	JSAMPARRAY row_pointer;
	JSAMPLE *buffer = NULL;
	int row_stride;
	int x, y, depth, r, g, b, k;
	struct ImBuf *ibuf = NULL;
	uchar *rect;
	jpeg_saved_marker_ptr marker;
	char *str, *key, *value;

	/* install own app1 handler */
	ibuf_quality = jpeg_default_quality;
	jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
	cinfo->dct_method = JDCT_FLOAT;
	jpeg_save_markers(cinfo, JPEG_COM, 0xffff);

	if (jpeg_read_header(cinfo, false) == JPEG_HEADER_OK) {
		x = cinfo->image_width;
		y = cinfo->image_height;
		depth = cinfo->num_components;

		if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK;

		jpeg_start_decompress(cinfo);

		if (flags & IB_test) {
			jpeg_abort_decompress(cinfo);
			ibuf = IMB_allocImBuf(x, y, 8 * depth, 0);
		}
		else if ((ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect)) == NULL) {
			jpeg_abort_decompress(cinfo);
		}
		else {
			row_stride = cinfo->output_width * depth;

			row_pointer = (*cinfo->mem->alloc_sarray)((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1);

			for (y = ibuf->y - 1; y >= 0; y--) {
				jpeg_read_scanlines(cinfo, row_pointer, 1);
				rect = (uchar *) (ibuf->rect + y * ibuf->x);
				buffer = row_pointer[0];

				switch (depth) {
					case 1:
						for (x = ibuf->x; x > 0; x--) {
							rect[3] = 255;
							rect[0] = rect[1] = rect[2] = *buffer++;
							rect += 4;
						}
						break;
					case 3:
						for (x = ibuf->x; x > 0; x--) {
							rect[3] = 255;
							rect[0] = *buffer++;
							rect[1] = *buffer++;
							rect[2] = *buffer++;
							rect += 4;
						}
						break;
					case 4:
						for (x = ibuf->x; x > 0; x--) {
							r = *buffer++;
							g = *buffer++;
							b = *buffer++;
							k = *buffer++;

							r = (r * k) / 255;
							g = (g * k) / 255;
							b = (b * k) / 255;

							rect[3] = 255;
							rect[2] = b;
							rect[1] = g;
							rect[0] = r;
							rect += 4;
						}
						break;
				}
			}

			marker = cinfo->marker_list;
			while (marker) {
				if (marker->marker != JPEG_COM)
					goto next_stamp_marker;

				/*
				 * JPEG marker strings are not null-terminated,
				 * create a null-terminated copy before going further
				 */
				str = BLI_strdupn((char *)marker->data, marker->data_length);

				/*
				 * Because JPEG format don't support the
				 * pair "key/value" like PNG, we store the
				 * stampinfo in a single "encode" string:
				 * "Blender:key:value"
				 *
				 * That is why we need split it to the
				 * common key/value here.
				 */
				if (!STREQLEN(str, "Blender", 7)) {
					/*
					 * Maybe the file have text that
					 * we don't know "what it's", in that
					 * case we keep the text (with a
					 * key "None").
					 * This is only for don't "lose"
					 * the information when we write
					 * it back to disk.
					 */
					IMB_metadata_ensure(&ibuf->metadata);
					IMB_metadata_set_field(ibuf->metadata, "None", str);
					ibuf->flags |= IB_metadata;
					MEM_freeN(str);
					goto next_stamp_marker;
				}

				key = strchr(str, ':');
				/*
				 * A little paranoid, but the file maybe
				 * is broken... and a "extra" check is better
				 * then segfault ;)
				 */
				if (!key) {
					MEM_freeN(str);
					goto next_stamp_marker;
				}

				key++;
				value = strchr(key, ':');
				if (!value) {
					MEM_freeN(str);
					goto next_stamp_marker;
				}

				*value = '\0'; /* need finish the key string */
				value++;
				IMB_metadata_ensure(&ibuf->metadata);
				IMB_metadata_set_field(ibuf->metadata, key, value);
				ibuf->flags |= IB_metadata;
				MEM_freeN(str);
next_stamp_marker:
				marker = marker->next;
			}

			jpeg_finish_decompress(cinfo);
		}

		jpeg_destroy((j_common_ptr) cinfo);
		if (ibuf) {
			ibuf->ftype = IMB_FTYPE_JPG;
			ibuf->foptions.quality = MIN2(ibuf_quality, 100);
		}
	}

	return(ibuf);
}
コード例 #10
0
ファイル: JPEG_band.cpp プロジェクト: hdfeos/gdal
CPLErr JPEG_Codec::DecompressJPEG(buf_mgr &dst, buf_mgr &isrc)
#endif

{
    int nbands = img.pagesize.c;
    // Locals, clean up after themselves
    jpeg_decompress_struct cinfo;
    MRFJPEGStruct sJPEGStruct;
    struct jpeg_error_mgr sJErr;
    BitMask mask(img.pagesize.x, img.pagesize.y);
    RLEC3Packer packer;
    mask.set_packer(&packer);

    memset(&cinfo, 0, sizeof(cinfo));
    // Pass the mask address to the decompressor
    sJPEGStruct.mask = &mask;

    struct jpeg_source_mgr src;

    cinfo.err = jpeg_std_error( &sJErr );
    sJErr.error_exit = errorExit;
    sJErr.emit_message = emitMessage;
    cinfo.client_data = (void *) &(sJPEGStruct);

    src.next_input_byte = (JOCTET *)isrc.buffer;
    src.bytes_in_buffer = isrc.size;
    src.term_source = stub_source_dec;
    src.init_source = stub_source_dec;
    src.skip_input_data = skip_input_data_dec;
    src.fill_input_buffer = fill_input_buffer_dec;
    src.resync_to_restart = jpeg_resync_to_restart;

    jpeg_create_decompress(&cinfo);

    if (setjmp(sJPEGStruct.setjmpBuffer)) {
        CPLError(CE_Failure, CPLE_AppDefined, "MRF: Error reading JPEG page");
        jpeg_destroy_decompress(&cinfo);
        return CE_Failure;
    }

    cinfo.src = &src;
    jpeg_set_marker_processor(&cinfo, JPEG_APP0 + 3, MaskProcessor);
    jpeg_read_header(&cinfo, TRUE);

    /* In some cases, libjpeg needs to allocate a lot of memory */
    /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
    if( jpeg_has_multiple_scans(&(cinfo)) )
    {
        /* In this case libjpeg will need to allocate memory or backing */
        /* store for all coefficients */
        /* See call to jinit_d_coef_controller() from master_selection() */
        /* in libjpeg */
        vsi_l_offset nRequiredMemory = 
            static_cast<vsi_l_offset>(cinfo.image_width) *
            cinfo.image_height * cinfo.num_components *
            ((cinfo.data_precision+7)/8);
        /* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */
        /* to replicate the logic of jinit_d_coef_controller() */
        if( cinfo.progressive_mode )
            nRequiredMemory *= 3;

#ifndef GDAL_LIBJPEG_LARGEST_MEM_ALLOC
#define GDAL_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024)
#endif

        if( nRequiredMemory > GDAL_LIBJPEG_LARGEST_MEM_ALLOC &&
            CPLGetConfigOption("GDAL_ALLOW_LARGE_LIBJPEG_MEM_ALLOC", nullptr) == nullptr )
        {
                CPLError(CE_Failure, CPLE_NotSupported,
                    "Reading this image would require libjpeg to allocate "
                    "at least " CPL_FRMT_GUIB " bytes. "
                    "This is disabled since above the " CPL_FRMT_GUIB " threshold. "
                    "You may override this restriction by defining the "
                    "GDAL_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
                    "or recompile GDAL by defining the "
                    "GDAL_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater "
                    "than " CPL_FRMT_GUIB,
                    static_cast<GUIntBig>(nRequiredMemory),
                    static_cast<GUIntBig>(GDAL_LIBJPEG_LARGEST_MEM_ALLOC),
                    static_cast<GUIntBig>(GDAL_LIBJPEG_LARGEST_MEM_ALLOC));
                jpeg_destroy_decompress(&cinfo);
                return CE_Failure;
        }
    }

    // Use float, it is actually faster than the ISLOW method by a tiny bit
    cinfo.dct_method = JDCT_FLOAT;

    //
    // Tolerate different input if we can do the conversion
    // Gray and RGB for example
    // This also means that a RGB MRF can be read as grayscale and vice versa
    // If libJPEG can't convert it will throw an error
    //
    if (nbands == 3 && cinfo.num_components != nbands)
        cinfo.out_color_space = JCS_RGB;
    if (nbands == 1 && cinfo.num_components != nbands)
        cinfo.out_color_space = JCS_GRAYSCALE;

    const int datasize = ((cinfo.data_precision == 8) ? 1 : 2);
    if( cinfo.image_width > static_cast<unsigned>(INT_MAX / (nbands * datasize)) )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "MRF: JPEG decompress buffer overflow");
        jpeg_destroy_decompress(&cinfo);
        return CE_Failure;
    }
    int linesize = cinfo.image_width * nbands * datasize;

    // We have a mismatch between the real and the declared data format
    // warn and fail if output buffer is too small
    if (linesize > static_cast<int>(INT_MAX / cinfo.image_height)) {
        CPLError(CE_Failure, CPLE_AppDefined, "MRF: JPEG decompress buffer overflow");
        jpeg_destroy_decompress(&cinfo);
        return CE_Failure;
    }
    if (linesize*cinfo.image_height != dst.size) {
        CPLError(CE_Warning, CPLE_AppDefined, "MRF: read JPEG size is wrong");
        if (linesize*cinfo.image_height > dst.size) {
            CPLError(CE_Failure, CPLE_AppDefined, "MRF: JPEG decompress buffer overflow");
            jpeg_destroy_decompress(&cinfo);
            return CE_Failure;
        }
    }

    struct jpeg_progress_mgr sJProgress;
    sJProgress.progress_monitor = ProgressMonitor;
    cinfo.progress = &sJProgress;

    jpeg_start_decompress(&cinfo);

    // Decompress, two lines at a time is what libjpeg does
    while (cinfo.output_scanline < cinfo.image_height) {
        char *rp[2];
        rp[0] = (char *)dst.buffer + linesize*cinfo.output_scanline;
        rp[1] = rp[0] + linesize;
        // if this fails, it calls the error handler
        // which will report an error
        if( jpeg_read_scanlines(&cinfo, JSAMPARRAY(rp), 2) == 0 )
        {
            jpeg_destroy_decompress(&cinfo);
            return CE_Failure;
        }
    }
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    // Apply the mask
    if (datasize == 1)
      apply_mask(sJPEGStruct, reinterpret_cast<char *>(dst.buffer), img.pagesize.c);
    else
      apply_mask(sJPEGStruct, reinterpret_cast<GUInt16 *>(dst.buffer), img.pagesize.c);

    return CE_None;
}
コード例 #11
0
ファイル: djpeg.c プロジェクト: jcyfkimi/libjpeg-turbo
int
main (int argc, char **argv)
{
    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;
    unsigned char *inbuffer = NULL;
    unsigned long insize = 0;
    JDIMENSION num_scanlines;

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

    progname = argv[0];
    if (progname == NULL || progname[0] == 0)
        progname = "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.txt).
     */
    jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
    jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);

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

    /* 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) &cinfo, &progress);
#endif

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

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

    /* Strip decode */
    if (strip || skip) {
        JDIMENSION tmp;

        /* Check for valid endY.  We cannot check this value until after
         * jpeg_start_decompress() is called.  Note that we have already verified
         * that startY <= endY.
         */
        if (endY > cinfo.output_height - 1) {
            fprintf(stderr, "%s: strip %d-%d exceeds image height %d\n", progname,
                    startY, endY, cinfo.output_height);
            exit(EXIT_FAILURE);
        }

        /* Write output file header.  This is a hack to ensure that the destination
         * manager creates an image of the proper size for the partial decode.
         */
        tmp = cinfo.output_height;
        cinfo.output_height = endY - startY + 1;
        if (skip)
            cinfo.output_height = tmp - cinfo.output_height;
        (*dest_mgr->start_output) (&cinfo, dest_mgr);
        cinfo.output_height = tmp;

        /* Process data */
        if (skip) {
            while (cinfo.output_scanline < startY) {
                num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
                                                    dest_mgr->buffer_height);
                (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
            }
            jpeg_skip_scanlines(&cinfo, endY - startY + 1);
            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);
            }
        } else {
            jpeg_skip_scanlines(&cinfo, startY);
            while (cinfo.output_scanline <= endY) {
                num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
                                                    dest_mgr->buffer_height);
                (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
            }
            jpeg_skip_scanlines(&cinfo, cinfo.output_height - endY + 1);
        }

        /* Normal full image decode */
    } else {
        /* 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);

    /* 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) &cinfo);
#endif

    if (memsrc && inbuffer != NULL)
        free(inbuffer);

    /* All done. */
    exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
    return 0;                     /* suppress no-return-value warnings */
}
コード例 #12
0
ファイル: jpeginfo.cpp プロジェクト: richardxday/rdlib
bool LoadJPEG(ACanvas *pC, const char *filename, ACanvas *pC1)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	JDIMENSION l, x, y, num_scanlines;
	AStdFile file;
	bool success = false;

	/* Initialize the JPEG decompression object with default error handling. */
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);

#if 0
	/* 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);
#endif

	if (file.open(filename, "rb")) {
		/* Specify data source for decompression */
		jpeg_stdio_src(&cinfo, file.GetFile());
		
		/* Read file header, set default decompression parameters */
		(void) jpeg_read_header(&cinfo, true);

		jpeg_start_decompress(&cinfo);

		if (!pC->Valid() || (pC->GetWidth() != (sint_t)cinfo.output_width) || (pC->GetHeight() != (sint_t)cinfo.output_height)) {
			pC->Delete();
			pC->CreateCompatibleDC(pC1);
			pC->CreateCompatibleBitmap(pC1, cinfo.output_width, cinfo.output_height);
		}

		if (pC->Valid()) {
			JSAMPLE *buffer;

			if ((buffer = new JSAMPLE[cinfo.output_width * cinfo.output_components]) != NULL) {
				success = true;
				y = 0;

				/* Process data */
				while (cinfo.output_scanline < cinfo.output_height) {
					num_scanlines = jpeg_read_scanlines(&cinfo, &buffer, 1);
					
					if (cinfo.output_components == 1) {
						for (l = 0; l < num_scanlines; l++, y++) {
							for (x = 0; x < cinfo.output_width; x++) {
								pC->SetPixelV(x, y, AColour(buffer[x], buffer[x], buffer[x]));
							}
						}
					}
					else if (cinfo.output_components == 3) {
						for (l = 0; l < num_scanlines; l++, y++) {
							for (x = 0; x < cinfo.output_width; x++) {
								pC->SetPixelV(x, y, AColour(buffer[x * 3], buffer[x * 3 + 1], buffer[x * 3 + 2]));
							}
						}
					}
					else {
						success = false;
						break;
					}
				}

				delete[] buffer;
			}

			/* Finish decompression and release memory.
			 * Must do it in this order because output module has allocated memory
			 * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
			 */
			(void) jpeg_finish_decompress(&cinfo);
		}

		file.close();
	}

	jpeg_destroy_decompress(&cinfo);

	return success;
}