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