spelling errors, no real changes to code.
[blender.git] / source / blender / imbuf / intern / jpeg.c
1 /**
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  * jpeg.c
28  *
29  * $Id$
30  */
31
32
33 /* This little block needed for linking to Blender... */
34 #include <stdio.h>
35 #include <setjmp.h>
36
37 #include "BLI_blenlib.h"
38
39 #include "imbuf.h"
40 #include "imbuf_patch.h"
41 #include "IMB_imbuf_types.h"
42 #include "IMB_imbuf.h"
43 #include "IMB_imginfo.h"
44 #include "IMB_jpeg.h"
45 #include "jpeglib.h" 
46 #include "jerror.h"
47
48 /* the types are from the jpeg lib */
49 static void jpeg_error (j_common_ptr cinfo);
50 static void init_source(j_decompress_ptr cinfo);
51 static boolean fill_input_buffer(j_decompress_ptr cinfo);
52 static void skip_input_data(j_decompress_ptr cinfo, long num_bytes);
53 static void term_source(j_decompress_ptr cinfo);
54 static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, int size);
55 static boolean handle_app1 (j_decompress_ptr cinfo);
56 static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags);
57
58
59 /*
60  * In principle there are 4 jpeg formats.
61  * 
62  * 1. jpeg - standard printing, u & v at quarter of resulution
63  * 2. jvid - standaard video, u & v half resolution, frame not interlaced
64
65 type 3 is unsupported as of jul 05 2000 Frank.
66
67  * 3. jstr - as 2, but written in 2 separate fields
68
69  * 4. jmax - no scaling in the components
70  */
71
72 static int jpeg_default_quality;
73 static int ibuf_ftype;
74
75 int imb_is_a_jpeg(unsigned char *mem) {
76
77         if ((mem[0]== 0xFF) && (mem[1] == 0xD8))return 1;
78         return 0;
79 }
80
81 //----------------------------------------------------------
82 //      JPG ERROR HANDLING
83 //----------------------------------------------------------
84
85 typedef struct my_error_mgr {
86   struct jpeg_error_mgr pub;    /* "public" fields */
87
88   jmp_buf setjmp_buffer;        /* for return to caller */
89 } my_error_mgr;
90
91 typedef my_error_mgr * my_error_ptr;
92
93 static void jpeg_error (j_common_ptr cinfo)
94 {
95         my_error_ptr err = (my_error_ptr)cinfo->err;
96
97         /* Always display the message */
98         (*cinfo->err->output_message) (cinfo);
99
100         /* Let the memory manager delete any temp files before we die */
101         jpeg_destroy(cinfo);
102
103         /* return control to the setjmp point */
104         longjmp(err->setjmp_buffer, 1);
105 }
106
107 //----------------------------------------------------------
108 //      INPUT HANDLER FROM MEMORY
109 //----------------------------------------------------------
110
111 typedef struct {
112         unsigned char   *buffer;
113         int             filled;
114 } buffer_struct;
115
116 typedef struct {
117         struct jpeg_source_mgr pub;     /* public fields */
118
119         unsigned char   *buffer;
120         int                             size;
121         JOCTET                  terminal[2];
122 } my_source_mgr;
123
124 typedef my_source_mgr * my_src_ptr;
125
126 static void init_source(j_decompress_ptr cinfo)
127 {
128 }
129
130
131 static boolean fill_input_buffer(j_decompress_ptr cinfo)
132 {
133         my_src_ptr src = (my_src_ptr) cinfo->src;
134
135         /* Since we have given all we have got already
136         * we simply fake an end of file
137         */
138
139         src->pub.next_input_byte = src->terminal;
140         src->pub.bytes_in_buffer = 2;
141         src->terminal[0] = (JOCTET) 0xFF;
142         src->terminal[1] = (JOCTET) JPEG_EOI;
143
144         return TRUE;
145 }
146
147
148 static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
149 {
150         my_src_ptr src = (my_src_ptr) cinfo->src;
151
152         src->pub.next_input_byte = src->pub.next_input_byte + num_bytes;
153 }
154
155
156 static void term_source(j_decompress_ptr cinfo)
157 {
158 }
159
160 static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, int size)
161 {
162         my_src_ptr src;
163
164         if (cinfo->src == NULL)
165         {       /* first time for this JPEG object? */
166                 cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)
167                         ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr));
168         }
169
170         src = (my_src_ptr) cinfo->src;
171         src->pub.init_source            = init_source;
172         src->pub.fill_input_buffer      = fill_input_buffer;
173         src->pub.skip_input_data        = skip_input_data;
174         src->pub.resync_to_restart      = jpeg_resync_to_restart; 
175         src->pub.term_source            = term_source;
176
177         src->pub.bytes_in_buffer        = size;
178         src->pub.next_input_byte        = buffer;
179
180         src->buffer = buffer;
181         src->size = size;
182 }
183
184
185 #define MAKESTMT(stuff)         do { stuff } while (0)
186
187 #define INPUT_VARS(cinfo)  \
188         struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
189         const JOCTET * next_input_byte = datasrc->next_input_byte;  \
190         size_t bytes_in_buffer = datasrc->bytes_in_buffer
191
192 /* Unload the local copies --- do this only at a restart boundary */
193 #define INPUT_SYNC(cinfo)  \
194         ( datasrc->next_input_byte = next_input_byte,  \
195           datasrc->bytes_in_buffer = bytes_in_buffer )
196
197 /* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */
198 #define INPUT_RELOAD(cinfo)  \
199         ( next_input_byte = datasrc->next_input_byte,  \
200           bytes_in_buffer = datasrc->bytes_in_buffer )
201
202 /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
203  * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
204  * but we must reload the local copies after a successful fill.
205  */
206 #define MAKE_BYTE_AVAIL(cinfo,action)  \
207         if (bytes_in_buffer == 0) {  \
208                 if (! (*datasrc->fill_input_buffer) (cinfo))  \
209                         { action; }  \
210                 INPUT_RELOAD(cinfo);  \
211         }  \
212         bytes_in_buffer--
213
214 /* Read a byte into variable V.
215  * If must suspend, take the specified action (typically "return FALSE").
216  */
217 #define INPUT_BYTE(cinfo,V,action)  \
218         MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
219                   V = GETJOCTET(*next_input_byte++); )
220
221 /* As above, but read two bytes interpreted as an unsigned 16-bit integer.
222  * V should be declared unsigned int or perhaps INT32.
223  */
224 #define INPUT_2BYTES(cinfo,V,action)  \
225         MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
226                   V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
227                   MAKE_BYTE_AVAIL(cinfo,action); \
228                   V += GETJOCTET(*next_input_byte++); )
229
230
231 static boolean
232 handle_app1 (j_decompress_ptr cinfo)
233 {
234         INT32 length, i;
235         char neogeo[128];
236         
237         INPUT_VARS(cinfo);
238
239         INPUT_2BYTES(cinfo, length, return FALSE);
240         length -= 2;
241         
242         if (length < 16) {
243                 for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return FALSE);
244                 length = 0;
245                 if (strncmp(neogeo, "NeoGeo", 6) == 0) memcpy(&ibuf_ftype, neogeo + 6, 4);
246                 ibuf_ftype = BIG_LONG(ibuf_ftype);
247         }
248         INPUT_SYNC(cinfo);              /* do before skip_input_data */
249         if (length > 0) (*cinfo->src->skip_input_data) (cinfo, length);
250         return TRUE;
251 }
252
253
254 static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags)
255 {
256         JSAMPARRAY row_pointer;
257         JSAMPLE * buffer = 0;
258         int row_stride;
259         int x, y, depth, r, g, b, k;
260         struct ImBuf * ibuf = 0;
261         uchar * rect;
262         jpeg_saved_marker_ptr marker;
263         char *str, *key, *value;
264
265         /* install own app1 handler */
266         ibuf_ftype = 0;
267         jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
268         cinfo->dct_method = JDCT_FLOAT;
269         jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
270
271         if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) {
272                 x = cinfo->image_width;
273                 y = cinfo->image_height;
274                 depth = cinfo->num_components;
275
276                 if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK;
277
278                 jpeg_start_decompress(cinfo);
279
280                 if (ibuf_ftype == 0) {
281                         ibuf_ftype = JPG_STD;
282                         if (cinfo->max_v_samp_factor == 1) {
283                                 if (cinfo->max_h_samp_factor == 1) ibuf_ftype = JPG_MAX;
284                                 else ibuf_ftype = JPG_VID;
285                         }
286                 }
287
288                 if (flags & IB_test) {
289                         jpeg_abort_decompress(cinfo);
290                         ibuf = IMB_allocImBuf(x, y, 8 * depth, 0, 0);
291                 } else {
292                         ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect, 0);
293
294                         row_stride = cinfo->output_width * depth;
295
296                         row_pointer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1);
297                         
298                         for (y = ibuf->y - 1; y >= 0; y--) {
299                                 jpeg_read_scanlines(cinfo, row_pointer, 1);
300                                 if (flags & IB_ttob) {
301                                         rect = (uchar *) (ibuf->rect + (ibuf->y - 1 - y) * ibuf->x);
302                                 } else {
303                                         rect = (uchar *) (ibuf->rect + y * ibuf->x);
304                                 }
305                                 buffer = row_pointer[0];
306                                 
307                                 switch(depth) {
308                                         case 1:
309                                                 for (x=ibuf->x; x >0; x--) {
310                                                         rect[3] = 255;
311                                                         rect[0] = rect[1] = rect[2] = *buffer++;
312                                                         rect += 4;
313                                                 }
314                                                         break;
315                                         case 3:
316                                                 for (x=ibuf->x; x >0; x--) {
317                                                         rect[3] = 255;
318                                                         rect[0] = *buffer++;
319                                                         rect[1] = *buffer++;
320                                                         rect[2] = *buffer++;
321                                                         rect += 4;
322                                                 }
323                                                         break;
324                                         case 4:
325                                                 for (x=ibuf->x; x >0; x--) {
326                                                         r = *buffer++;
327                                                         g = *buffer++;
328                                                         b = *buffer++;
329                                                         k = *buffer++;
330                                                         
331                                                         k = 255 - k;
332                                                         r -= k;
333                                                         if (r & 0xffffff00) {
334                                                                 if (r < 0) r = 0;
335                                                                 else r = 255;
336                                                         }
337                                                         g -= k;
338                                                         if (g & 0xffffff00) {
339                                                                 if (g < 0) g = 0;
340                                                                 else g = 255;
341                                                         }
342                                                         b -= k;
343                                                         if (b & 0xffffff00) {
344                                                                 if (b < 0) b = 0;
345                                                                 else b = 255;
346                                                         }                                                       
347                                                         
348                                                         rect[3] = 255 - k;
349                                                         rect[2] = b;
350                                                         rect[1] = g;
351                                                         rect[0] = r;
352                                                         rect += 4;
353                                                 }
354                                 }
355                         }
356
357                         marker= cinfo->marker_list;
358                         while(marker) {
359                                 if(marker->marker != JPEG_COM)
360                                         goto next_stamp_marker;
361
362                                 /*
363                                  * Because JPEG format don't support the
364                                  * pair "key/value" like PNG, we store the
365                                  * stampinfo in a single "encode" string:
366                                  *      "Blender:key:value"
367                                  *
368                                  * That is why we need split it to the
369                                  * common key/value here.
370                                  */
371                                 if(strncmp((char *) marker->data, "Blender", 7)) {
372                                         /*
373                                          * Maybe the file have text that
374                                          * we don't know "what it's", in that
375                                          * case we keep the text (with a
376                                          * key "None").
377                                          * This is only for don't "lose"
378                                          * the information when we write
379                                          * it back to disk.
380                                          */
381                                         IMB_imginfo_add_field(ibuf, "None", (char *) marker->data);
382                                         ibuf->flags |= IB_imginfo;
383                                         goto next_stamp_marker;
384                                 }
385
386                                 str = BLI_strdup ((char *) marker->data);
387                                 key = strchr (str, ':');
388                                 /*
389                                  * A little paranoid, but the file maybe
390                                  * is broken... and a "extra" check is better
391                                  * that a segfaul ;)
392                                  */
393                                 if (!key) {
394                                         MEM_freeN(str);
395                                         goto next_stamp_marker;
396                                 }
397
398                                 key++;
399                                 value = strchr (key, ':');
400                                 if (!value) {
401                                         MEM_freeN(str);
402                                         goto next_stamp_marker;
403                                 }
404
405                                 *value = '\0'; /* need finish the key string */
406                                 value++;
407                                 IMB_imginfo_add_field(ibuf, key, value);
408                                 ibuf->flags |= IB_imginfo;
409                                 MEM_freeN(str);
410 next_stamp_marker:
411                                 marker= marker->next;
412                         }
413
414                         jpeg_finish_decompress(cinfo);
415                 }
416                 
417                 jpeg_destroy((j_common_ptr) cinfo);
418                 ibuf->ftype = ibuf_ftype;
419                 ibuf->profile = IB_PROFILE_SRGB;
420         }
421         
422         return(ibuf);
423 }
424
425 ImBuf * imb_ibJpegImageFromFilename (const char * filename, int flags)
426 {
427         struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
428         struct my_error_mgr jerr;
429         FILE * infile;
430         ImBuf * ibuf;
431         
432         if ((infile = fopen(filename, "rb")) == NULL) return 0;
433
434         cinfo->err = jpeg_std_error(&jerr.pub);
435         jerr.pub.error_exit = jpeg_error;
436
437         /* Establish the setjmp return context for my_error_exit to use. */
438         if (setjmp(jerr.setjmp_buffer)) {
439                 /* If we get here, the JPEG code has signaled an error.
440                  * We need to clean up the JPEG object, close the input file, and return.
441                  */
442                 jpeg_destroy_decompress(cinfo);
443                 fclose(infile);
444                 return NULL;
445         }
446
447         jpeg_create_decompress(cinfo);
448         jpeg_stdio_src(cinfo, infile);
449
450         ibuf = ibJpegImageFromCinfo(cinfo, flags);
451         
452         fclose(infile);
453         return(ibuf);
454 }
455
456 ImBuf * imb_ibJpegImageFromMemory (unsigned char * buffer, int size, int flags)
457 {
458         struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
459         struct my_error_mgr jerr;
460         ImBuf * ibuf;
461         
462         cinfo->err = jpeg_std_error(&jerr.pub);
463         jerr.pub.error_exit = jpeg_error;
464
465         /* Establish the setjmp return context for my_error_exit to use. */
466         if (setjmp(jerr.setjmp_buffer)) {
467                 /* If we get here, the JPEG code has signaled an error.
468                  * We need to clean up the JPEG object, close the input file, and return.
469                  */
470                 jpeg_destroy_decompress(cinfo);
471                 return NULL;
472         }
473
474         jpeg_create_decompress(cinfo);
475         memory_source(cinfo, buffer, size);
476
477         ibuf = ibJpegImageFromCinfo(cinfo, flags);
478         
479         return(ibuf);
480 }
481
482
483 static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf)
484 {
485         JSAMPLE * buffer = 0;
486         JSAMPROW row_pointer[1];
487         uchar * rect;
488         int x, y;
489         char neogeo[128];
490         ImgInfo *iptr;
491         char *text;
492
493         jpeg_start_compress(cinfo, TRUE);
494
495         strcpy(neogeo, "NeoGeo");
496         ibuf_ftype = BIG_LONG(ibuf->ftype);
497         
498         memcpy(neogeo + 6, &ibuf_ftype, 4);
499         jpeg_write_marker(cinfo, 0xe1, (JOCTET*) neogeo, 10);
500
501         if(ibuf->img_info) {
502                 /* key + max value + "Blender" */
503                 text= MEM_mallocN(530, "stamp info read");
504                 iptr= ibuf->img_info;
505                 while(iptr) {
506                         if (!strcmp (iptr->key, "None")) {
507                                 jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) iptr->value, strlen (iptr->value) + 1);
508                                 goto next_stamp_info;
509                         }
510
511                         /*
512                          * The JPEG format don't support a pair "key/value"
513                          * like PNG, so we "encode" the stamp in a
514                          * single string:
515                          *      "Blender:key:value"
516                          *
517                          * The first "Blender" is a simple identify to help
518                          * in the read process.
519                          */
520                         sprintf (text, "Blender:%s:%s", iptr->key, iptr->value);
521                         jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, strlen (text)+1);
522 next_stamp_info:
523                         iptr = iptr->next;
524                 }
525                 MEM_freeN(text);
526         }
527
528         row_pointer[0] =
529                 mallocstruct(JSAMPLE,
530                                          cinfo->input_components *
531                                          cinfo->image_width);
532
533         for(y = ibuf->y - 1; y >= 0; y--){
534                 rect = (uchar *) (ibuf->rect + y * ibuf->x);
535                 buffer = row_pointer[0];
536
537                 switch(cinfo->in_color_space){
538                 case JCS_RGB:
539                         for (x = 0; x < ibuf->x; x++) {
540                                 *buffer++ = rect[0];
541                                 *buffer++ = rect[1];
542                                 *buffer++ = rect[2];
543                                 rect += 4;
544                         }
545                         break;
546                 case JCS_GRAYSCALE:
547                         for (x = 0; x < ibuf->x; x++) {
548                                 *buffer++ = rect[0];
549                                 rect += 4;
550                         }
551                         break;
552                 case JCS_UNKNOWN:
553                         memcpy(buffer, rect, 4 * ibuf->x);
554                         break;
555                         /* default was missing... intentional ? */
556                 default:
557                         ; /* do nothing */
558                 }
559
560                 jpeg_write_scanlines(cinfo, row_pointer, 1);
561         }
562
563         jpeg_finish_compress(cinfo);
564         free(row_pointer[0]);
565 }
566
567
568 static int init_jpeg(FILE * outfile, struct jpeg_compress_struct * cinfo, struct ImBuf *ibuf)
569 {
570         int quality;
571
572         quality = ibuf->ftype & 0xff;
573         if (quality <= 0) quality = jpeg_default_quality;
574         if (quality > 100) quality = 100;
575
576         jpeg_create_compress(cinfo);
577         jpeg_stdio_dest(cinfo, outfile);
578
579         cinfo->image_width = ibuf->x;
580         cinfo->image_height = ibuf->y;
581
582         cinfo->in_color_space = JCS_RGB;
583         if (ibuf->depth == 8 && ibuf->cmap == 0) cinfo->in_color_space = JCS_GRAYSCALE;
584         if (ibuf->depth == 32) cinfo->in_color_space = JCS_UNKNOWN;
585         
586         switch(cinfo->in_color_space){
587         case JCS_RGB:
588                 cinfo->input_components = 3;
589                 break;
590         case JCS_GRAYSCALE:
591                 cinfo->input_components = 1;
592                 break;
593         case JCS_UNKNOWN:
594                 cinfo->input_components = 4;
595                 break;
596                 /* default was missing... intentional ? */
597         default:
598                 ; /* do nothing */
599         }
600         jpeg_set_defaults(cinfo);
601         
602         /* own settings */
603
604         cinfo->dct_method = JDCT_FLOAT;
605         jpeg_set_quality(cinfo, quality, TRUE);
606
607         return(0);
608 }
609
610
611 static int save_stdjpeg(char * name, struct ImBuf * ibuf)
612 {
613         FILE * outfile;
614         struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
615         struct my_error_mgr jerr;
616
617         if ((outfile = fopen(name, "wb")) == NULL) return 0;
618         jpeg_default_quality = 75;
619
620         cinfo->err = jpeg_std_error(&jerr.pub);
621         jerr.pub.error_exit = jpeg_error;
622
623         /* Establish the setjmp return context for jpeg_error to use. */
624         if (setjmp(jerr.setjmp_buffer)) {
625                 /* If we get here, the JPEG code has signaled an error.
626                  * We need to clean up the JPEG object, close the input file, and return.
627                  */
628                 jpeg_destroy_compress(cinfo);
629                 fclose(outfile);
630                 remove(name);
631                 return 0;
632         }
633
634         init_jpeg(outfile, cinfo, ibuf);
635
636         write_jpeg(cinfo, ibuf);
637
638         fclose(outfile);
639         jpeg_destroy_compress(cinfo);
640
641         return 1;
642 }
643
644
645 static int save_vidjpeg(char * name, struct ImBuf * ibuf)
646 {
647         FILE * outfile;
648         struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
649         struct my_error_mgr jerr;
650
651         if ((outfile = fopen(name, "wb")) == NULL) return 0;
652         jpeg_default_quality = 90;
653
654         cinfo->err = jpeg_std_error(&jerr.pub);
655         jerr.pub.error_exit = jpeg_error;
656
657         /* Establish the setjmp return context for jpeg_error to use. */
658         if (setjmp(jerr.setjmp_buffer)) {
659                 /* If we get here, the JPEG code has signaled an error.
660                  * We need to clean up the JPEG object, close the input file, and return.
661                  */
662                 jpeg_destroy_compress(cinfo);
663                 fclose(outfile);
664                 remove(name);
665                 return 0;
666         }
667
668         init_jpeg(outfile, cinfo, ibuf);
669
670         /* adjust scaling factors */
671         if (cinfo->in_color_space == JCS_RGB) {
672                 cinfo->comp_info[0].h_samp_factor = 2;
673                 cinfo->comp_info[0].v_samp_factor = 1;
674         }
675
676         write_jpeg(cinfo, ibuf);
677
678         fclose(outfile);
679         jpeg_destroy_compress(cinfo);
680
681         return 1;
682 }
683
684 static int save_jstjpeg(char * name, struct ImBuf * ibuf)
685 {
686         char fieldname[1024];
687         struct ImBuf * tbuf;
688         int oldy, returnval;
689
690         tbuf = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 24, IB_rect, 0);
691         tbuf->ftype = ibuf->ftype;
692         tbuf->flags = ibuf->flags;
693         
694         oldy = ibuf->y;
695         ibuf->x *= 2;
696         ibuf->y /= 2;
697
698         IMB_rectcpy(tbuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
699         sprintf(fieldname, "%s.jf0", name);
700
701         returnval = save_vidjpeg(fieldname, tbuf) ;
702         if (returnval == 1) {
703                 IMB_rectcpy(tbuf, ibuf, 0, 0, tbuf->x, 0, ibuf->x, ibuf->y);
704                 sprintf(fieldname, "%s.jf1", name);
705                 returnval = save_vidjpeg(fieldname, tbuf);
706         }
707
708         ibuf->y = oldy;
709         ibuf->x /= 2;
710         IMB_freeImBuf(tbuf);
711
712         return returnval;
713 }
714
715 static int save_maxjpeg(char * name, struct ImBuf * ibuf)
716 {
717         FILE * outfile;
718         struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
719         struct my_error_mgr jerr;
720
721         if ((outfile = fopen(name, "wb")) == NULL) return 0;
722         jpeg_default_quality = 100;
723
724         cinfo->err = jpeg_std_error(&jerr.pub);
725         jerr.pub.error_exit = jpeg_error;
726
727         /* Establish the setjmp return context for jpeg_error to use. */
728         if (setjmp(jerr.setjmp_buffer)) {
729                 /* If we get here, the JPEG code has signaled an error.
730                  * We need to clean up the JPEG object, close the input file, and return.
731                  */
732                 jpeg_destroy_compress(cinfo);
733                 fclose(outfile);
734                 remove(name);
735                 return 0;
736         }
737
738         init_jpeg(outfile, cinfo, ibuf);
739
740         /* adjust scaling factors */
741         if (cinfo->in_color_space == JCS_RGB) {
742                 cinfo->comp_info[0].h_samp_factor = 1;
743                 cinfo->comp_info[0].v_samp_factor = 1;
744         }
745
746         write_jpeg(cinfo, ibuf);
747
748         fclose(outfile);
749         jpeg_destroy_compress(cinfo);
750
751         return 1;
752 }
753
754 int imb_savejpeg(struct ImBuf * ibuf, char * name, int flags)
755 {
756         
757         ibuf->flags = flags;
758         if (IS_stdjpg(ibuf)) return save_stdjpeg(name, ibuf);
759         if (IS_jstjpg(ibuf)) return save_jstjpeg(name, ibuf);
760         if (IS_maxjpg(ibuf)) return save_maxjpeg(name, ibuf);
761         return save_vidjpeg(name, ibuf);
762 }
763