GLOBAL void
jpeg_destroy_decompress (j_decompress_ptr cinfo)
{
  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
}
Beispiel #2
0
static void iJpegErrorExit( j_common_ptr cinfo )
{
	ilSetError( IL_LIB_JPEG_ERROR );
	jpeg_destroy( cinfo );
	longjmp( JpegJumpBuffer, 1 );
}
Beispiel #3
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);
}
Beispiel #4
0
void jpeg_exit(j_common_ptr jpeg_ptr) {
  jpeg_ptr->err->output_message(jpeg_ptr);
  if (jpeg_ptr->err->msg_code != JERR_UNKNOWN_MARKER) {
    jpeg_destroy(jpeg_ptr);
  }
}
Beispiel #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_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);
}
// Load JPG from memory
unsigned char* LoadJPGWithAlphaFromMemory(const unsigned char* begin, int len, int* width, int* height)
{
	jpeg_decompress_struct cinfo;
	jpeg_error_mgr jerr;
	
	cinfo.err=jpeg_std_error(&jerr);
	jerr.error_exit=error_jpeg_exit;

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

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

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

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

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

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

		}
		delete []data_temp;

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

		*width=wi;
		*height=he;

		return data;
	}
	#ifdef ENABLE_JPG_EXCEPTION
	catch (...)
	{
		jpeg_destroy((j_common_ptr)&cinfo);
		return NULL;
	}
	#endif
}