Blender  V2.59
jpeg.c
Go to the documentation of this file.
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