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