GLOBAL void jpeg_destroy_decompress (j_decompress_ptr cinfo) { jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ }
static void iJpegErrorExit( j_common_ptr cinfo ) { ilSetError( IL_LIB_JPEG_ERROR ); jpeg_destroy( cinfo ); longjmp( JpegJumpBuffer, 1 ); }
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); }
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); } }
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 }