Merge branch 'master' of http://www-dev.cockos.com/wdl/WDL into updatewdl
[wdl/wdl-ol.git] / WDL / lice / lice_jpg_write.cpp
blob0f8621ee8c56dcac5319477db3da57e35a2f4ee7
1 /*
2 Cockos WDL - LICE - Lightweight Image Compositing Engine
3 Copyright (C) 2007 and later, Cockos Incorporated
4 File: lice_jpg_write.cpp (JPG writing for LICE)
5 See lice.h for license and other information
6 */
8 #include <stdio.h>
9 #include "lice.h"
10 #include <setjmp.h>
12 extern "C" {
13 #include "../jpeglib/jpeglib.h"
16 struct my_error_mgr {
17 struct jpeg_error_mgr pub; /* "public" fields */
18 jmp_buf setjmp_buffer; /* for return to caller */
20 static void LICEJPEG_Error(j_common_ptr cinfo)
22 longjmp(((my_error_mgr*)cinfo->err)->setjmp_buffer,1);
24 static void LICEJPEG_EmitMsg(j_common_ptr cinfo, int msg_level) { }
25 static void LICEJPEG_FmtMsg(j_common_ptr cinfo, char *) { }
26 static void LICEJPEG_OutMsg(j_common_ptr cinfo) { }
27 static void LICEJPEG_reset_error_mgr(j_common_ptr cinfo)
29 cinfo->err->num_warnings = 0;
30 cinfo->err->msg_code = 0;
33 bool LICE_WriteJPG(const char *filename, LICE_IBitmap *bmp, int quality, bool force_baseline)
35 if (!bmp || !filename) return false;
37 FILE *fp=NULL;
38 #if defined(_WIN32) && !defined(WDL_NO_SUPPORT_UTF8)
39 #ifdef WDL_SUPPORT_WIN9X
40 if (GetVersion()<0x80000000)
41 #endif
43 WCHAR wf[2048];
44 if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,filename,-1,wf,2048))
45 fp = _wfopen(wf,L"wb");
47 #endif
48 if (!fp) fp = fopen(filename,"wb");
50 if (!fp) return false;
52 struct jpeg_compress_struct cinfo;
53 struct my_error_mgr jerr={0,};
54 jerr.pub.error_exit = LICEJPEG_Error;
55 jerr.pub.emit_message = LICEJPEG_EmitMsg;
56 jerr.pub.output_message = LICEJPEG_OutMsg;
57 jerr.pub.format_message = LICEJPEG_FmtMsg;
58 jerr.pub.reset_error_mgr = LICEJPEG_reset_error_mgr;
60 cinfo.err = &jerr.pub;
61 unsigned char *buf = NULL;
63 if (setjmp(jerr.setjmp_buffer))
65 jpeg_destroy_compress(&cinfo);
66 if (fp) fclose(fp);
67 free(buf);
68 return false;
70 jpeg_create_compress(&cinfo);
72 jpeg_stdio_dest(&cinfo, fp);
74 cinfo.image_width = bmp->getWidth(); /* image width and height, in pixels */
75 cinfo.image_height = bmp->getHeight();
76 cinfo.input_components = 3; /* # of color components per pixel */
77 cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
79 jpeg_set_defaults(&cinfo);
80 jpeg_set_quality(&cinfo, quality, !!force_baseline);
81 jpeg_start_compress(&cinfo, TRUE);
83 buf = (unsigned char *)malloc(cinfo.image_width * 3);
84 LICE_pixel_chan *rd = (LICE_pixel_chan *)bmp->getBits();
85 int rowspan = bmp->getRowSpan()*4;
86 if (bmp->isFlipped())
88 rd += rowspan*(bmp->getHeight()-1);
89 rowspan=-rowspan;
91 while (cinfo.next_scanline < cinfo.image_height)
93 unsigned char *outp=buf;
94 LICE_pixel_chan *rdp = rd;
95 int x=cinfo.image_width;
96 while(x--)
98 outp[0] = rdp[LICE_PIXEL_R];
99 outp[1] = rdp[LICE_PIXEL_G];
100 outp[2] = rdp[LICE_PIXEL_B];
101 outp+=3;
102 rdp+=4;
104 jpeg_write_scanlines(&cinfo, &buf, 1);
106 rd+=rowspan;
108 free(buf);
109 buf=0;
111 jpeg_finish_compress(&cinfo);
113 if (fp) fclose(fp);
114 fp=0;
116 jpeg_destroy_compress(&cinfo);
118 return true;