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