Exemple #1
0
static gboolean
gdk_pixbuf__jpeg_image_load_lines (JpegProgContext  *context,
                                   GError          **error)
{
        struct jpeg_decompress_struct *cinfo = &context->cinfo;
        guchar *lines[4];
        guchar **lptr;
        guchar *rowptr;
        gint   nlines, i;

        /* keep going until we've done all scanlines */
        while (cinfo->output_scanline < cinfo->output_height) {
                lptr = lines;
                rowptr = context->dptr;
                for (i=0; i < cinfo->rec_outbuf_height; i++) {
                        *lptr++ = rowptr;
                        rowptr += context->pixbuf->rowstride;
                }

                nlines = jpeg_read_scanlines (cinfo, lines,
                                              cinfo->rec_outbuf_height);
                if (nlines == 0)
                        break;

                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:
                        if (error && *error == NULL) {
                                g_set_error (error,
                                             GDK_PIXBUF_ERROR,
                                             GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
                                             _("Unsupported JPEG color space (%s)"),
                                             colorspace_name (cinfo->out_color_space));
                        }

                        return FALSE;
                }

                context->dptr += nlines * context->pixbuf->rowstride;

                /* send updated signal */
		if (context->updated_func)
			(* context->updated_func) (context->pixbuf,
						   0,
						   cinfo->output_scanline - 1,
						   cinfo->image_width,
						   nlines,
						   context->user_data);
        }

        return TRUE;
}
Exemple #2
0
static void
print_verbose_info_about_header(struct jpeg_decompress_struct const cinfo){

    struct jpeg_marker_struct * markerP;

    pm_message("input color space is %d (%s)\n", 
               cinfo.jpeg_color_space, 
               colorspace_name(cinfo.jpeg_color_space));

    /* Note that raw information about marker, including marker type code,
       was already printed by the jpeg library, due to the jpeg library
       trace level >= 1.  Our job is to interpret it a little bit.
    */
    if (cinfo.marker_list)
        pm_message("Miscellaneous markers (excluding APP0, APP12) "
                   "in header:");
    else
        pm_message("No miscellaneous markers (excluding APP0, APP12) "
                   "in header");
    for (markerP = cinfo.marker_list; markerP; markerP = markerP->next) {
        if (markerP->marker == JPEG_COM)
            pm_message("Comment marker (COM):");
        else if (markerP->marker >= JPEG_APP0 && 
                 markerP->marker <= JPEG_APP0+15)
            pm_message("Miscellaneous marker type APP%d:", 
                       markerP->marker - JPEG_APP0);
        else
            pm_message("Miscellaneous marker of unknown type (0x%X):",
                       markerP->marker);
        
        print_marker(*markerP);
    }
}
Exemple #3
0
/* Shared library entry point */
static GdkPixbuf *
gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
{
	gint   i;
	int     is_otag;
	char   otag_str[5];
	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;
        jerr.pub.output_message = output_message_handler;
        jerr.error = error;
        
	if (sigsetjmp (jerr.setjmp_buffer, 1)) {
		/* Whoops there was a jpeg error */
		if (pixbuf)
			g_object_unref (pixbuf);

		jpeg_destroy_decompress (&cinfo);

		/* error should have been set by fatal_error_handler () */
		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_save_markers (&cinfo, EXIF_JPEG_MARKER, 0xffff);
	jpeg_read_header (&cinfo, TRUE);

	/* check for orientation tag */
	is_otag = get_orientation (&cinfo);
	
	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);

                /* broken check for *error == NULL for robustness against
                 * crappy JPEG library
                 */
                if (error && *error == NULL) {
                        g_set_error_literal (error,
                                             GDK_PIXBUF_ERROR,
                                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                                             _("Insufficient memory to load image, try exiting some applications to free memory"));
                }
                
		return NULL;
	}

	/* if orientation tag was found set an option to remember its value */
	if (is_otag) {
		g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
		gdk_pixbuf_set_option (pixbuf, "orientation", otag_str);
	}


	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:
		      g_object_unref (pixbuf);
		      if (error && *error == NULL) {
                        g_set_error (error,
                                     GDK_PIXBUF_ERROR,
				     GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
				     _("Unsupported JPEG color space (%s)"),
				     colorspace_name (cinfo.out_color_space)); 
		      }
                
		      jpeg_destroy_decompress (&cinfo);
		      return NULL;
		}
	}

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

	return pixbuf;
}