Blender V2.61 - r43446

jpeg.c

Go to the documentation of this file.
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