|
Blender
V2.59
|
00001 /* 00002 * 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 * jpeg.c 00028 * 00029 * $Id: jpeg.c 36276 2011-04-21 15:53:30Z campbellbarton $ 00030 */ 00031 00038 /* This little block needed for linking to Blender... */ 00039 #include <stdio.h> 00040 #include <setjmp.h> 00041 00042 #include "MEM_guardedalloc.h" 00043 00044 #include "BLI_blenlib.h" 00045 00046 #include "imbuf.h" 00047 #include "IMB_imbuf_types.h" 00048 #include "IMB_imbuf.h" 00049 #include "IMB_metadata.h" 00050 #include "IMB_filetype.h" 00051 #include "jpeglib.h" 00052 #include "jerror.h" 00053 00054 #define IS_jpg(x) (x->ftype & JPG) 00055 #define IS_stdjpg(x) ((x->ftype & JPG_MSK) == JPG_STD) 00056 #define IS_vidjpg(x) ((x->ftype & JPG_MSK) == JPG_VID) 00057 #define IS_jstjpg(x) ((x->ftype & JPG_MSK) == JPG_JST) 00058 #define IS_maxjpg(x) ((x->ftype & JPG_MSK) == JPG_MAX) 00059 00060 /* the types are from the jpeg lib */ 00061 static void jpeg_error (j_common_ptr cinfo); 00062 static void init_source(j_decompress_ptr cinfo); 00063 static boolean fill_input_buffer(j_decompress_ptr cinfo); 00064 static void skip_input_data(j_decompress_ptr cinfo, long num_bytes); 00065 static void term_source(j_decompress_ptr cinfo); 00066 static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t size); 00067 static boolean handle_app1 (j_decompress_ptr cinfo); 00068 static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags); 00069 00070 00071 /* 00072 * In principle there are 4 jpeg formats. 00073 * 00074 * 1. jpeg - standard printing, u & v at quarter of resulution 00075 * 2. jvid - standaard video, u & v half resolution, frame not interlaced 00076 00077 type 3 is unsupported as of jul 05 2000 Frank. 00078 00079 * 3. jstr - as 2, but written in 2 separate fields 00080 00081 * 4. jmax - no scaling in the components 00082 */ 00083 00084 static int jpeg_default_quality; 00085 static int ibuf_ftype; 00086 00087 int imb_is_a_jpeg(unsigned char *mem) { 00088 00089 if ((mem[0]== 0xFF) && (mem[1] == 0xD8))return 1; 00090 return 0; 00091 } 00092 00093 //---------------------------------------------------------- 00094 // JPG ERROR HANDLING 00095 //---------------------------------------------------------- 00096 00097 typedef struct my_error_mgr { 00098 struct jpeg_error_mgr pub; /* "public" fields */ 00099 00100 jmp_buf setjmp_buffer; /* for return to caller */ 00101 } my_error_mgr; 00102 00103 typedef my_error_mgr * my_error_ptr; 00104 00105 static void jpeg_error (j_common_ptr cinfo) 00106 { 00107 my_error_ptr err = (my_error_ptr)cinfo->err; 00108 00109 /* Always display the message */ 00110 (*cinfo->err->output_message) (cinfo); 00111 00112 /* Let the memory manager delete any temp files before we die */ 00113 jpeg_destroy(cinfo); 00114 00115 /* return control to the setjmp point */ 00116 longjmp(err->setjmp_buffer, 1); 00117 } 00118 00119 //---------------------------------------------------------- 00120 // INPUT HANDLER FROM MEMORY 00121 //---------------------------------------------------------- 00122 00123 typedef struct { 00124 unsigned char *buffer; 00125 int filled; 00126 } buffer_struct; 00127 00128 typedef struct { 00129 struct jpeg_source_mgr pub; /* public fields */ 00130 00131 unsigned char *buffer; 00132 int size; 00133 JOCTET terminal[2]; 00134 } my_source_mgr; 00135 00136 typedef my_source_mgr * my_src_ptr; 00137 00138 static void init_source(j_decompress_ptr cinfo) 00139 { 00140 (void)cinfo; /* unused */ 00141 } 00142 00143 00144 static boolean fill_input_buffer(j_decompress_ptr cinfo) 00145 { 00146 my_src_ptr src = (my_src_ptr) cinfo->src; 00147 00148 /* Since we have given all we have got already 00149 * we simply fake an end of file 00150 */ 00151 00152 src->pub.next_input_byte = src->terminal; 00153 src->pub.bytes_in_buffer = 2; 00154 src->terminal[0] = (JOCTET) 0xFF; 00155 src->terminal[1] = (JOCTET) JPEG_EOI; 00156 00157 return TRUE; 00158 } 00159 00160 00161 static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) 00162 { 00163 my_src_ptr src = (my_src_ptr) cinfo->src; 00164 00165 if(num_bytes > 0) { 00166 // prevent skipping over file end 00167 size_t skip_size = (size_t)num_bytes <= src->pub.bytes_in_buffer ? num_bytes : src->pub.bytes_in_buffer; 00168 00169 src->pub.next_input_byte = src->pub.next_input_byte + skip_size; 00170 src->pub.bytes_in_buffer = src->pub.bytes_in_buffer - skip_size; 00171 } 00172 } 00173 00174 00175 static void term_source(j_decompress_ptr cinfo) 00176 { 00177 (void)cinfo; /* unused */ 00178 } 00179 00180 static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t size) 00181 { 00182 my_src_ptr src; 00183 00184 if (cinfo->src == NULL) 00185 { /* first time for this JPEG object? */ 00186 cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) 00187 ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr)); 00188 } 00189 00190 src = (my_src_ptr) cinfo->src; 00191 src->pub.init_source = init_source; 00192 src->pub.fill_input_buffer = fill_input_buffer; 00193 src->pub.skip_input_data = skip_input_data; 00194 src->pub.resync_to_restart = jpeg_resync_to_restart; 00195 src->pub.term_source = term_source; 00196 00197 src->pub.bytes_in_buffer = size; 00198 src->pub.next_input_byte = buffer; 00199 00200 src->buffer = buffer; 00201 src->size = size; 00202 } 00203 00204 00205 #define MAKESTMT(stuff) do { stuff } while (0) 00206 00207 #define INPUT_VARS(cinfo) \ 00208 struct jpeg_source_mgr * datasrc = (cinfo)->src; \ 00209 const JOCTET * next_input_byte = datasrc->next_input_byte; \ 00210 size_t bytes_in_buffer = datasrc->bytes_in_buffer 00211 00212 /* Unload the local copies --- do this only at a restart boundary */ 00213 #define INPUT_SYNC(cinfo) \ 00214 ( datasrc->next_input_byte = next_input_byte, \ 00215 datasrc->bytes_in_buffer = bytes_in_buffer ) 00216 00217 /* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */ 00218 #define INPUT_RELOAD(cinfo) \ 00219 ( next_input_byte = datasrc->next_input_byte, \ 00220 bytes_in_buffer = datasrc->bytes_in_buffer ) 00221 00222 /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. 00223 * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, 00224 * but we must reload the local copies after a successful fill. 00225 */ 00226 #define MAKE_BYTE_AVAIL(cinfo,action) \ 00227 if (bytes_in_buffer == 0) { \ 00228 if (! (*datasrc->fill_input_buffer) (cinfo)) \ 00229 { action; } \ 00230 INPUT_RELOAD(cinfo); \ 00231 } 00232 00233 00234 00235 /* Read a byte into variable V. 00236 * If must suspend, take the specified action (typically "return FALSE"). 00237 */ 00238 #define INPUT_BYTE(cinfo,V,action) \ 00239 MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ 00240 bytes_in_buffer--; \ 00241 V = GETJOCTET(*next_input_byte++); ) 00242 00243 /* As above, but read two bytes interpreted as an unsigned 16-bit integer. 00244 * V should be declared unsigned int or perhaps INT32. 00245 */ 00246 #define INPUT_2BYTES(cinfo,V,action) \ 00247 MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ 00248 bytes_in_buffer--; \ 00249 V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ 00250 MAKE_BYTE_AVAIL(cinfo,action); \ 00251 bytes_in_buffer--; \ 00252 V += GETJOCTET(*next_input_byte++); ) 00253 00254 00255 static boolean 00256 handle_app1 (j_decompress_ptr cinfo) 00257 { 00258 INT32 length, i; 00259 char neogeo[128]; 00260 00261 INPUT_VARS(cinfo); 00262 00263 length = 0; 00264 INPUT_2BYTES(cinfo, length, return FALSE); 00265 length -= 2; 00266 00267 if (length < 16) { 00268 for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return FALSE); 00269 length = 0; 00270 if (strncmp(neogeo, "NeoGeo", 6) == 0) memcpy(&ibuf_ftype, neogeo + 6, 4); 00271 ibuf_ftype = BIG_LONG(ibuf_ftype); 00272 } 00273 INPUT_SYNC(cinfo); /* do before skip_input_data */ 00274 if (length > 0) (*cinfo->src->skip_input_data) (cinfo, length); 00275 return TRUE; 00276 } 00277 00278 00279 static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags) 00280 { 00281 JSAMPARRAY row_pointer; 00282 JSAMPLE * buffer = NULL; 00283 int row_stride; 00284 int x, y, depth, r, g, b, k; 00285 struct ImBuf * ibuf = NULL; 00286 uchar * rect; 00287 jpeg_saved_marker_ptr marker; 00288 char *str, *key, *value; 00289 00290 /* install own app1 handler */ 00291 ibuf_ftype = 0; 00292 jpeg_set_marker_processor(cinfo, 0xe1, handle_app1); 00293 cinfo->dct_method = JDCT_FLOAT; 00294 jpeg_save_markers(cinfo, JPEG_COM, 0xffff); 00295 00296 if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) { 00297 x = cinfo->image_width; 00298 y = cinfo->image_height; 00299 depth = cinfo->num_components; 00300 00301 if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK; 00302 00303 jpeg_start_decompress(cinfo); 00304 00305 if (ibuf_ftype == 0) { 00306 ibuf_ftype = JPG_STD; 00307 if (cinfo->max_v_samp_factor == 1) { 00308 if (cinfo->max_h_samp_factor == 1) ibuf_ftype = JPG_MAX; 00309 else ibuf_ftype = JPG_VID; 00310 } 00311 } 00312 00313 if (flags & IB_test) { 00314 jpeg_abort_decompress(cinfo); 00315 ibuf = IMB_allocImBuf(x, y, 8 * depth, 0); 00316 } 00317 else if ((ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect)) == NULL) { 00318 jpeg_abort_decompress(cinfo); 00319 } 00320 else { 00321 row_stride = cinfo->output_width * depth; 00322 00323 row_pointer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1); 00324 00325 for (y = ibuf->y - 1; y >= 0; y--) { 00326 jpeg_read_scanlines(cinfo, row_pointer, 1); 00327 rect = (uchar *) (ibuf->rect + y * ibuf->x); 00328 buffer = row_pointer[0]; 00329 00330 switch(depth) { 00331 case 1: 00332 for (x=ibuf->x; x >0; x--) { 00333 rect[3] = 255; 00334 rect[0] = rect[1] = rect[2] = *buffer++; 00335 rect += 4; 00336 } 00337 break; 00338 case 3: 00339 for (x=ibuf->x; x >0; x--) { 00340 rect[3] = 255; 00341 rect[0] = *buffer++; 00342 rect[1] = *buffer++; 00343 rect[2] = *buffer++; 00344 rect += 4; 00345 } 00346 break; 00347 case 4: 00348 for (x=ibuf->x; x >0; x--) { 00349 r = *buffer++; 00350 g = *buffer++; 00351 b = *buffer++; 00352 k = *buffer++; 00353 00354 k = 255 - k; 00355 r -= k; 00356 if (r & 0xffffff00) { 00357 if (r < 0) r = 0; 00358 else r = 255; 00359 } 00360 g -= k; 00361 if (g & 0xffffff00) { 00362 if (g < 0) g = 0; 00363 else g = 255; 00364 } 00365 b -= k; 00366 if (b & 0xffffff00) { 00367 if (b < 0) b = 0; 00368 else b = 255; 00369 } 00370 00371 rect[3] = 255 - k; 00372 rect[2] = b; 00373 rect[1] = g; 00374 rect[0] = r; 00375 rect += 4; 00376 } 00377 } 00378 } 00379 00380 marker= cinfo->marker_list; 00381 while(marker) { 00382 if(marker->marker != JPEG_COM) 00383 goto next_stamp_marker; 00384 00385 /* 00386 * Because JPEG format don't support the 00387 * pair "key/value" like PNG, we store the 00388 * stampinfo in a single "encode" string: 00389 * "Blender:key:value" 00390 * 00391 * That is why we need split it to the 00392 * common key/value here. 00393 */ 00394 if(strncmp((char *) marker->data, "Blender", 7)) { 00395 /* 00396 * Maybe the file have text that 00397 * we don't know "what it's", in that 00398 * case we keep the text (with a 00399 * key "None"). 00400 * This is only for don't "lose" 00401 * the information when we write 00402 * it back to disk. 00403 */ 00404 IMB_metadata_add_field(ibuf, "None", (char *) marker->data); 00405 ibuf->flags |= IB_metadata; 00406 goto next_stamp_marker; 00407 } 00408 00409 str = BLI_strdup ((char *) marker->data); 00410 key = strchr (str, ':'); 00411 /* 00412 * A little paranoid, but the file maybe 00413 * is broken... and a "extra" check is better 00414 * that a segfaul ;) 00415 */ 00416 if (!key) { 00417 MEM_freeN(str); 00418 goto next_stamp_marker; 00419 } 00420 00421 key++; 00422 value = strchr (key, ':'); 00423 if (!value) { 00424 MEM_freeN(str); 00425 goto next_stamp_marker; 00426 } 00427 00428 *value = '\0'; /* need finish the key string */ 00429 value++; 00430 IMB_metadata_add_field(ibuf, key, value); 00431 ibuf->flags |= IB_metadata; 00432 MEM_freeN(str); 00433 next_stamp_marker: 00434 marker= marker->next; 00435 } 00436 00437 jpeg_finish_decompress(cinfo); 00438 } 00439 00440 jpeg_destroy((j_common_ptr) cinfo); 00441 if(ibuf) { 00442 ibuf->ftype = ibuf_ftype; 00443 ibuf->profile = IB_PROFILE_SRGB; 00444 } 00445 } 00446 00447 return(ibuf); 00448 } 00449 00450 ImBuf * imb_load_jpeg (unsigned char * buffer, size_t size, int flags) 00451 { 00452 struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo; 00453 struct my_error_mgr jerr; 00454 ImBuf * ibuf; 00455 00456 if(!imb_is_a_jpeg(buffer)) return NULL; 00457 00458 cinfo->err = jpeg_std_error(&jerr.pub); 00459 jerr.pub.error_exit = jpeg_error; 00460 00461 /* Establish the setjmp return context for my_error_exit to use. */ 00462 if (setjmp(jerr.setjmp_buffer)) { 00463 /* If we get here, the JPEG code has signaled an error. 00464 * We need to clean up the JPEG object, close the input file, and return. 00465 */ 00466 jpeg_destroy_decompress(cinfo); 00467 return NULL; 00468 } 00469 00470 jpeg_create_decompress(cinfo); 00471 memory_source(cinfo, buffer, size); 00472 00473 ibuf = ibJpegImageFromCinfo(cinfo, flags); 00474 00475 return(ibuf); 00476 } 00477 00478 00479 static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf) 00480 { 00481 JSAMPLE * buffer = NULL; 00482 JSAMPROW row_pointer[1]; 00483 uchar * rect; 00484 int x, y; 00485 char neogeo[128]; 00486 ImMetaData *iptr; 00487 char *text; 00488 00489 jpeg_start_compress(cinfo, TRUE); 00490 00491 strcpy(neogeo, "NeoGeo"); 00492 ibuf_ftype = BIG_LONG(ibuf->ftype); 00493 00494 memcpy(neogeo + 6, &ibuf_ftype, 4); 00495 jpeg_write_marker(cinfo, 0xe1, (JOCTET*) neogeo, 10); 00496 00497 if(ibuf->metadata) { 00498 /* key + max value + "Blender" */ 00499 text= MEM_mallocN(530, "stamp info read"); 00500 iptr= ibuf->metadata; 00501 while(iptr) { 00502 if (!strcmp (iptr->key, "None")) { 00503 jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) iptr->value, strlen (iptr->value) + 1); 00504 goto next_stamp_info; 00505 } 00506 00507 /* 00508 * The JPEG format don't support a pair "key/value" 00509 * like PNG, so we "encode" the stamp in a 00510 * single string: 00511 * "Blender:key:value" 00512 * 00513 * The first "Blender" is a simple identify to help 00514 * in the read process. 00515 */ 00516 sprintf (text, "Blender:%s:%s", iptr->key, iptr->value); 00517 jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, strlen (text)+1); 00518 next_stamp_info: 00519 iptr = iptr->next; 00520 } 00521 MEM_freeN(text); 00522 } 00523 00524 row_pointer[0] = 00525 MEM_mallocN(sizeof(JSAMPLE) * 00526 cinfo->input_components * 00527 cinfo->image_width, "jpeg row_pointer"); 00528 00529 for(y = ibuf->y - 1; y >= 0; y--){ 00530 rect = (uchar *) (ibuf->rect + y * ibuf->x); 00531 buffer = row_pointer[0]; 00532 00533 switch(cinfo->in_color_space){ 00534 case JCS_RGB: 00535 for (x = 0; x < ibuf->x; x++) { 00536 *buffer++ = rect[0]; 00537 *buffer++ = rect[1]; 00538 *buffer++ = rect[2]; 00539 rect += 4; 00540 } 00541 break; 00542 case JCS_GRAYSCALE: 00543 for (x = 0; x < ibuf->x; x++) { 00544 *buffer++ = rect[0]; 00545 rect += 4; 00546 } 00547 break; 00548 case JCS_UNKNOWN: 00549 memcpy(buffer, rect, 4 * ibuf->x); 00550 break; 00551 /* default was missing... intentional ? */ 00552 default: 00553 ; /* do nothing */ 00554 } 00555 00556 jpeg_write_scanlines(cinfo, row_pointer, 1); 00557 } 00558 00559 jpeg_finish_compress(cinfo); 00560 MEM_freeN(row_pointer[0]); 00561 } 00562 00563 00564 static int init_jpeg(FILE * outfile, struct jpeg_compress_struct * cinfo, struct ImBuf *ibuf) 00565 { 00566 int quality; 00567 00568 quality = ibuf->ftype & 0xff; 00569 if (quality <= 0) quality = jpeg_default_quality; 00570 if (quality > 100) quality = 100; 00571 00572 jpeg_create_compress(cinfo); 00573 jpeg_stdio_dest(cinfo, outfile); 00574 00575 cinfo->image_width = ibuf->x; 00576 cinfo->image_height = ibuf->y; 00577 00578 cinfo->in_color_space = JCS_RGB; 00579 if (ibuf->depth == 8) cinfo->in_color_space = JCS_GRAYSCALE; 00580 if (ibuf->depth == 32) cinfo->in_color_space = JCS_UNKNOWN; 00581 00582 switch(cinfo->in_color_space){ 00583 case JCS_RGB: 00584 cinfo->input_components = 3; 00585 break; 00586 case JCS_GRAYSCALE: 00587 cinfo->input_components = 1; 00588 break; 00589 case JCS_UNKNOWN: 00590 cinfo->input_components = 4; 00591 break; 00592 /* default was missing... intentional ? */ 00593 default: 00594 ; /* do nothing */ 00595 } 00596 jpeg_set_defaults(cinfo); 00597 00598 /* own settings */ 00599 00600 cinfo->dct_method = JDCT_FLOAT; 00601 jpeg_set_quality(cinfo, quality, TRUE); 00602 00603 return(0); 00604 } 00605 00606 00607 static int save_stdjpeg(const char *name, struct ImBuf *ibuf) 00608 { 00609 FILE * outfile; 00610 struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; 00611 struct my_error_mgr jerr; 00612 00613 if ((outfile = fopen(name, "wb")) == NULL) return 0; 00614 jpeg_default_quality = 75; 00615 00616 cinfo->err = jpeg_std_error(&jerr.pub); 00617 jerr.pub.error_exit = jpeg_error; 00618 00619 /* Establish the setjmp return context for jpeg_error to use. */ 00620 if (setjmp(jerr.setjmp_buffer)) { 00621 /* If we get here, the JPEG code has signaled an error. 00622 * We need to clean up the JPEG object, close the input file, and return. 00623 */ 00624 jpeg_destroy_compress(cinfo); 00625 fclose(outfile); 00626 remove(name); 00627 return 0; 00628 } 00629 00630 init_jpeg(outfile, cinfo, ibuf); 00631 00632 write_jpeg(cinfo, ibuf); 00633 00634 fclose(outfile); 00635 jpeg_destroy_compress(cinfo); 00636 00637 return 1; 00638 } 00639 00640 00641 static int save_vidjpeg(const char *name, struct ImBuf *ibuf) 00642 { 00643 FILE * outfile; 00644 struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; 00645 struct my_error_mgr jerr; 00646 00647 if ((outfile = fopen(name, "wb")) == NULL) return 0; 00648 jpeg_default_quality = 90; 00649 00650 cinfo->err = jpeg_std_error(&jerr.pub); 00651 jerr.pub.error_exit = jpeg_error; 00652 00653 /* Establish the setjmp return context for jpeg_error to use. */ 00654 if (setjmp(jerr.setjmp_buffer)) { 00655 /* If we get here, the JPEG code has signaled an error. 00656 * We need to clean up the JPEG object, close the input file, and return. 00657 */ 00658 jpeg_destroy_compress(cinfo); 00659 fclose(outfile); 00660 remove(name); 00661 return 0; 00662 } 00663 00664 init_jpeg(outfile, cinfo, ibuf); 00665 00666 /* adjust scaling factors */ 00667 if (cinfo->in_color_space == JCS_RGB) { 00668 cinfo->comp_info[0].h_samp_factor = 2; 00669 cinfo->comp_info[0].v_samp_factor = 1; 00670 } 00671 00672 write_jpeg(cinfo, ibuf); 00673 00674 fclose(outfile); 00675 jpeg_destroy_compress(cinfo); 00676 00677 return 1; 00678 } 00679 00680 static int save_jstjpeg(const char *name, struct ImBuf *ibuf) 00681 { 00682 char fieldname[1024]; 00683 struct ImBuf * tbuf; 00684 int oldy, returnval; 00685 00686 tbuf = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 24, IB_rect); 00687 tbuf->ftype = ibuf->ftype; 00688 tbuf->flags = ibuf->flags; 00689 00690 oldy = ibuf->y; 00691 ibuf->x *= 2; 00692 ibuf->y /= 2; 00693 00694 IMB_rectcpy(tbuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); 00695 sprintf(fieldname, "%s.jf0", name); 00696 00697 returnval = save_vidjpeg(fieldname, tbuf) ; 00698 if (returnval == 1) { 00699 IMB_rectcpy(tbuf, ibuf, 0, 0, tbuf->x, 0, ibuf->x, ibuf->y); 00700 sprintf(fieldname, "%s.jf1", name); 00701 returnval = save_vidjpeg(fieldname, tbuf); 00702 } 00703 00704 ibuf->y = oldy; 00705 ibuf->x /= 2; 00706 IMB_freeImBuf(tbuf); 00707 00708 return returnval; 00709 } 00710 00711 static int save_maxjpeg(const char *name, struct ImBuf *ibuf) 00712 { 00713 FILE * outfile; 00714 struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; 00715 struct my_error_mgr jerr; 00716 00717 if ((outfile = fopen(name, "wb")) == NULL) return 0; 00718 jpeg_default_quality = 100; 00719 00720 cinfo->err = jpeg_std_error(&jerr.pub); 00721 jerr.pub.error_exit = jpeg_error; 00722 00723 /* Establish the setjmp return context for jpeg_error to use. */ 00724 if (setjmp(jerr.setjmp_buffer)) { 00725 /* If we get here, the JPEG code has signaled an error. 00726 * We need to clean up the JPEG object, close the input file, and return. 00727 */ 00728 jpeg_destroy_compress(cinfo); 00729 fclose(outfile); 00730 remove(name); 00731 return 0; 00732 } 00733 00734 init_jpeg(outfile, cinfo, ibuf); 00735 00736 /* adjust scaling factors */ 00737 if (cinfo->in_color_space == JCS_RGB) { 00738 cinfo->comp_info[0].h_samp_factor = 1; 00739 cinfo->comp_info[0].v_samp_factor = 1; 00740 } 00741 00742 write_jpeg(cinfo, ibuf); 00743 00744 fclose(outfile); 00745 jpeg_destroy_compress(cinfo); 00746 00747 return 1; 00748 } 00749 00750 int imb_savejpeg(struct ImBuf *ibuf, const char *name, int flags) 00751 { 00752 00753 ibuf->flags = flags; 00754 if (IS_stdjpg(ibuf)) return save_stdjpeg(name, ibuf); 00755 if (IS_jstjpg(ibuf)) return save_jstjpeg(name, ibuf); 00756 if (IS_maxjpg(ibuf)) return save_maxjpeg(name, ibuf); 00757 return save_vidjpeg(name, ibuf); 00758 } 00759