Initial revision
[swftools.git] / lib / modules / swfbits.c
1 /* swfbits.c\r
2 \r
3    Bitmap functions (needs libjpeg) \r
4 \r
5    Extension module for the rfxswf library.\r
6    Part of the swftools package.\r
7 \r
8    Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>\r
9  \r
10    This file is distributed under the GPL, see file COPYING for details \r
11 \r
12 */\r
13 \r
14 #ifdef _JPEGLIB_INCLUDED_\r
15 #define OUTBUFFER_SIZE 32768\r
16 \r
17 typedef struct _JPEGDESTMGR\r
18 { struct jpeg_destination_mgr mgr;\r
19   LPTAG  t;\r
20   JOCTET * buffer;\r
21   struct jpeg_compress_struct cinfo;\r
22   struct jpeg_error_mgr jerr;\r
23 } JPEGDESTMGR, * LPJPEGDESTMGR;\r
24 \r
25 // Destination manager callbacks\r
26 \r
27 void swf_init_destination(j_compress_ptr cinfo) \r
28 { LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest;\r
29   dmgr->buffer = (JOCTET*)malloc(OUTBUFFER_SIZE);\r
30   dmgr->mgr.next_output_byte = dmgr->buffer;\r
31   dmgr->mgr.free_in_buffer = OUTBUFFER_SIZE;\r
32 }\r
33 \r
34 boolean swf_empty_output_buffer(j_compress_ptr cinfo)\r
35 { LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest;\r
36   SetBlock(dmgr->t,\r
37            (U8*)dmgr->buffer,\r
38            OUTBUFFER_SIZE-dmgr->mgr.free_in_buffer);\r
39   dmgr->mgr.next_output_byte = dmgr->buffer;\r
40   dmgr->mgr.free_in_buffer = OUTBUFFER_SIZE;\r
41 }\r
42 \r
43 void swf_term_destination(j_compress_ptr cinfo) \r
44 { LPJPEGDESTMGR dmgr = (LPJPEGDESTMGR)cinfo->dest;\r
45   swf_empty_output_buffer(cinfo);\r
46   free(dmgr->buffer);\r
47   dmgr->mgr.free_in_buffer = 0;\r
48 }\r
49 \r
50 LPJPEGBITS SetJPEGBitsStart(LPTAG t,int width,int height,int quality)\r
51 {\r
52   LPJPEGDESTMGR jpeg;\r
53         \r
54   // redirect compression lib output to local SWF Tag structure\r
55   \r
56   jpeg = (LPJPEGDESTMGR)malloc(sizeof(JPEGDESTMGR));\r
57   if (!jpeg) return NULL;\r
58   \r
59   memset(jpeg,0x00,sizeof(JPEGDESTMGR));\r
60   jpeg->cinfo.err = jpeg_std_error(&jpeg->jerr);\r
61 \r
62   jpeg_create_compress(&jpeg->cinfo);\r
63 \r
64   jpeg->mgr.init_destination =  swf_init_destination;\r
65   jpeg->mgr.empty_output_buffer =       swf_empty_output_buffer;\r
66   jpeg->mgr.term_destination =  swf_term_destination;\r
67       \r
68   jpeg->t = t;\r
69 \r
70   jpeg->cinfo.dest = (struct jpeg_destination_mgr *)jpeg;\r
71 \r
72   // init compression\r
73   \r
74   jpeg->cinfo.image_width  = width;\r
75   jpeg->cinfo.image_height = height;\r
76   jpeg->cinfo.input_components = 3;\r
77   jpeg->cinfo.in_color_space = JCS_RGB;\r
78 \r
79   jpeg_set_defaults(&jpeg->cinfo);\r
80   jpeg_set_quality(&jpeg->cinfo,quality,TRUE);\r
81 \r
82   // write tables to SWF\r
83   \r
84   jpeg_write_tables(&jpeg->cinfo);\r
85 \r
86   // compess image to SWF\r
87    \r
88   jpeg_suppress_tables(&jpeg->cinfo, TRUE);\r
89   jpeg_start_compress(&jpeg->cinfo, FALSE);\r
90 \r
91   return (LPJPEGBITS)jpeg;\r
92 }\r
93 \r
94 int SetJPEGBitsLines(LPJPEGBITS jpegbits,U8 ** data,int n)\r
95 { LPJPEGDESTMGR jpeg = (LPJPEGDESTMGR)jpegbits;\r
96   if (!jpeg) return -1;\r
97   jpeg_write_scanlines(&jpeg->cinfo,data,n);\r
98   return 0;\r
99 }\r
100 \r
101 int SetJPEGBitsLine(LPJPEGBITS jpegbits,U8 * data)\r
102 { return SetJPEGBitsLines(jpegbits,&data,1);\r
103 }\r
104 \r
105 int SetJPEGBitsFinish(LPJPEGBITS jpegbits)\r
106 { LPJPEGDESTMGR jpeg = (LPJPEGDESTMGR)jpegbits;\r
107   if (!jpeg) return -1;\r
108   jpeg_finish_compress(&jpeg->cinfo);\r
109   free(jpeg);\r
110   return 0;\r
111 }\r
112 \r
113 int SetJPEGBits(LPTAG t,char * fname,int quality)\r
114 { struct jpeg_decompress_struct cinfo;\r
115   struct jpeg_error_mgr jerr;\r
116   LPJPEGBITS out;\r
117   FILE * f;\r
118   U8 * scanline;\r
119   \r
120   cinfo.err = jpeg_std_error(&jerr);\r
121   jpeg_create_decompress(&cinfo); \r
122 \r
123   if ((f=fopen(fname,"rb"))==NULL) return -1;\r
124   \r
125 \r
126   jpeg_stdio_src(&cinfo,f);\r
127   jpeg_read_header(&cinfo, TRUE);\r
128   jpeg_start_decompress(&cinfo);\r
129 \r
130   out = SetJPEGBitsStart(t,cinfo.output_width,cinfo.output_height,quality);\r
131   scanline = (U8*)malloc(4*cinfo.output_width);\r
132   \r
133   if (scanline)\r
134   { int y;\r
135     U8 * js = scanline;\r
136     for (y=0;y<cinfo.output_height;y++)\r
137     { jpeg_read_scanlines(&cinfo,&js,1);\r
138       SetJPEGBitsLines(out,(U8**)&js,1);\r
139     }\r
140   }\r
141 \r
142   SetJPEGBitsFinish(out);\r
143   jpeg_finish_decompress(&cinfo);\r
144   fclose(f);\r
145   \r
146   return 0;\r
147 }\r
148 \r
149 #undef OUTBUFFER_SIZE\r
150 #endif\r
151 \r
152 // insert zlib/PNG functions here\r