summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/bitmap.cc
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/multimedia/opieplayer/libflash/bitmap.cc
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'core/multimedia/opieplayer/libflash/bitmap.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/bitmap.cc606
1 files changed, 606 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/bitmap.cc b/core/multimedia/opieplayer/libflash/bitmap.cc
new file mode 100644
index 0000000..03b4588
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/bitmap.cc
@@ -0,0 +1,606 @@
1/////////////////////////////////////////////////////////////
2// Flash Plugin and Player
3// Copyright (C) 1998 Olivier Debon
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
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19///////////////////////////////////////////////////////////////
20// Author : Olivier Debon <odebon@club-internet.fr>
21//
22
23#include "swf.h"
24
25#ifdef RCSID
26static char *rcsid = "$Id$";
27#endif
28
29static unsigned char *inputData;
30
31// Class variables
32
33int Bitmap::haveTables = 0;
34
35struct jpeg_decompress_struct Bitmap::jpegObject;
36
37struct jpeg_source_mgr Bitmap::jpegSourceManager;
38
39MyErrorHandler Bitmap::jpegErrorMgr;
40
41Bitmap::Bitmap(long id, int level) : Character(BitmapType, id )
42{
43 pixels = NULL;
44 alpha_buf = NULL;
45 colormap = NULL;
46 nbColors = 0;
47 defLevel = level;
48}
49
50Bitmap::~Bitmap()
51{
52 if (pixels) {
53 delete[] pixels;
54 }
55 if (alpha_buf) {
56 delete[] alpha_buf;
57 }
58 if (colormap)
59 {
60 delete colormap;
61 }
62 if (haveTables) {
63 jpeg_destroy_decompress(&jpegObject);
64 haveTables = 0;
65 }
66}
67
68static void errorExit(j_common_ptr info)
69{
70 (*info->err->output_message) (info);
71 longjmp(((MyErrorHandler *)info->err)->setjmp_buffer, 1);
72}
73
74// Methods for Source data manager
75static void initSource(struct jpeg_decompress_struct *cInfo)
76{
77 cInfo->src->bytes_in_buffer = 0;
78}
79
80static boolean fillInputBuffer(struct jpeg_decompress_struct *cInfo)
81{
82 cInfo->src->next_input_byte = inputData;
83 cInfo->src->bytes_in_buffer = 1;
84 inputData++;
85
86 return 1;
87}
88
89static void skipInputData(struct jpeg_decompress_struct *cInfo, long count)
90{
91 cInfo->src->bytes_in_buffer = 0;
92 inputData += count;
93}
94
95static boolean resyncToRestart(struct jpeg_decompress_struct *cInfo, int desired)
96{
97 return jpeg_resync_to_restart(cInfo, desired);
98}
99
100static void termSource(struct jpeg_decompress_struct *cInfo)
101{
102}
103
104long Bitmap::getWidth()
105{
106 return width;
107}
108
109long Bitmap::getHeight()
110{
111 return height;
112}
113
114Color *
115Bitmap::getColormap(long *n) {
116 if (n) *n = nbColors;
117 return colormap;
118}
119
120unsigned char *
121Bitmap::getPixels()
122{
123 return pixels;
124}
125
126// Read Tables and Compressed data to produce an image
127
128static int
129buildJpegAlpha(Bitmap *b, unsigned char *buffer)
130{
131 z_streamstream;
132 int status;
133 unsigned char *data;
134
135 data = new unsigned char[b->width*b->height];
136 if (data == NULL)
137 return -1;
138
139 stream.next_in = buffer;
140 stream.avail_in = 1;
141 stream.next_out = data;
142 stream.avail_out = b->width*b->height;
143 stream.zalloc = Z_NULL;
144 stream.zfree = Z_NULL;
145
146 status = inflateInit(&stream);
147
148 while (1) {
149 status = inflate(&stream, Z_SYNC_FLUSH) ;
150 if (status == Z_STREAM_END) {
151 break;
152 }
153 if (status != Z_OK) {
154 printf("Zlib data error : %s\n", stream.msg);
155 delete data;
156 return -1;
157 }
158 stream.avail_in = 1;
159 }
160
161 inflateEnd(&stream);
162
163 b->alpha_buf = data;
164
165 return 0;
166}
167
168int
169Bitmap::buildFromJpegInterchangeData(unsigned char *stream, int read_alpha, long offset)
170{
171 struct jpeg_decompress_struct cInfo;
172 struct jpeg_source_mgr mySrcMgr;
173 MyErrorHandler errorMgr;
174 JSAMPROW buffer[1];
175 unsigned char *ptrPix;
176 int stride;
177 long n;
178
179#if PRINT&1
180 printf("flash: loading jpeg (interchange)\n");
181#endif
182
183 // Kludge to correct some corrupted files
184 if (stream[1] == 0xd9 && stream[3] == 0xd8) {
185 stream[3] = 0xd9;
186 stream[1] = 0xd8;
187 }
188
189 // Setup error handler
190 cInfo.err = jpeg_std_error(&errorMgr.pub);
191 errorMgr.pub.error_exit = errorExit;
192
193 if (setjmp(errorMgr.setjmp_buffer)) {
194 // JPEG data Error
195 jpeg_destroy_decompress(&cInfo);
196 if (pixels) {
197 delete[] pixels;
198 pixels = NULL;
199 }
200 return -1;
201 }
202
203 // Set current stream pointer to stream
204 inputData = stream;
205
206 // Here it's Ok
207
208 jpeg_create_decompress(&cInfo);
209
210 // Setup source manager structure
211 mySrcMgr.init_source = initSource;
212 mySrcMgr.fill_input_buffer = fillInputBuffer;
213 mySrcMgr.skip_input_data = skipInputData;
214 mySrcMgr.resync_to_restart = resyncToRestart;
215 mySrcMgr.term_source = termSource;
216
217 // Set default source manager
218 cInfo.src = &mySrcMgr;
219
220 jpeg_read_header(&cInfo, FALSE);
221
222 jpeg_read_header(&cInfo, TRUE);
223 cInfo.quantize_colors = TRUE;// Create colormapped image
224 jpeg_start_decompress(&cInfo);
225
226 // Set objet dimensions
227 height = cInfo.output_height;
228 width = cInfo.output_width;
229 bpl = width;
230 pixels = new unsigned char [height*width];
231 if (pixels == NULL) {
232 jpeg_finish_decompress(&cInfo);
233 jpeg_destroy_decompress(&cInfo);
234 return -1;
235 }
236 ptrPix = pixels;
237
238 stride = cInfo.output_width * cInfo.output_components;
239
240 buffer[0] = (JSAMPROW)malloc(stride);
241
242 while (cInfo.output_scanline < cInfo.output_height) {
243
244 jpeg_read_scanlines(&cInfo, buffer, 1);
245
246 memcpy(ptrPix,buffer[0],stride);
247
248 ptrPix+= stride;
249 }
250
251 free(buffer[0]);
252
253 colormap = new Color[cInfo.actual_number_of_colors];
254 if (colormap == NULL) {
255 delete pixels;
256 jpeg_finish_decompress(&cInfo);
257 jpeg_destroy_decompress(&cInfo);
258 return -1;
259 }
260 nbColors = cInfo.actual_number_of_colors;
261
262 for(n=0; n < nbColors; n++)
263 {
264 colormap[n].red = cInfo.colormap[0][n];
265 colormap[n].green = cInfo.colormap[1][n];
266 colormap[n].blue = cInfo.colormap[2][n];
267 }
268
269 jpeg_finish_decompress(&cInfo);
270 jpeg_destroy_decompress(&cInfo);
271
272 if (read_alpha) {
273 if (buildJpegAlpha(this, stream + offset) < 0) {
274 return -1;
275 }
276 }
277 return 0;
278}
279
280// Read JPEG image using pre-loaded Tables
281
282int
283Bitmap::buildFromJpegAbbreviatedData(unsigned char *stream)
284{
285 JSAMPROW buffer[1];
286 unsigned char *ptrPix;
287 int stride;
288 long n;
289 int status;
290
291#if PRINT&1
292 printf("flash: loading jpeg (abbreviated)\n");
293#endif
294
295 // Set current stream pointer to stream
296 inputData = stream;
297
298 // Error handler
299 if (setjmp(jpegErrorMgr.setjmp_buffer)) {
300 // JPEG data Error
301 //jpeg_destroy_decompress(&jpegObject);
302 if (pixels) {
303 delete[] pixels;
304 pixels = NULL;
305 }
306 return -1;
307 }
308
309 // Here it's ok
310
311 jpeg_read_header(&jpegObject, TRUE);
312 jpegObject.quantize_colors = TRUE;// Create colormapped image
313 jpeg_start_decompress(&jpegObject);
314
315 // Set objet dimensions
316 height = jpegObject.output_height;
317 width = jpegObject.output_width;
318 bpl = width;
319 pixels = new unsigned char [height*width];
320 if (pixels == NULL) {
321 jpeg_finish_decompress(&jpegObject);
322 return -1;
323 }
324 ptrPix = pixels;
325
326 stride = jpegObject.output_width * jpegObject.output_components;
327
328 buffer[0] = (JSAMPROW)malloc(stride);
329
330 while (jpegObject.output_scanline < jpegObject.output_height) {
331
332 status = jpeg_read_scanlines(&jpegObject, buffer, 1);
333
334 memcpy(ptrPix,buffer[0],stride);
335
336 ptrPix+= stride;
337 }
338
339 free(buffer[0]);
340
341 colormap = new Color[jpegObject.actual_number_of_colors];
342 if (colormap == NULL) {
343 jpeg_finish_decompress(&jpegObject);
344 delete pixels;
345 return -1;
346 }
347 nbColors = jpegObject.actual_number_of_colors;
348
349 for(n=0; n < nbColors; n++)
350 {
351 colormap[n].red = jpegObject.colormap[0][n];
352 colormap[n].green = jpegObject.colormap[1][n];
353 colormap[n].blue = jpegObject.colormap[2][n];
354 }
355
356 status = jpeg_finish_decompress(&jpegObject);
357
358 return 0;
359}
360
361// Just init JPEG object and read JPEG Tables
362
363int
364Bitmap::readJpegTables(unsigned char *stream)
365{
366 if (haveTables) {
367 //Error, it has already been initialized
368 return -1;
369 }
370
371 // Setup error handler
372 jpegObject.err = jpeg_std_error(&jpegErrorMgr.pub);
373 jpegErrorMgr.pub.error_exit = errorExit;
374
375 if (setjmp(jpegErrorMgr.setjmp_buffer)) {
376 // JPEG data Error
377 jpeg_destroy_decompress(&jpegObject);
378 return -1;
379 }
380
381 // Set current stream pointer to stream
382 inputData = stream;
383
384 // Here it's Ok
385
386 jpeg_create_decompress(&jpegObject);
387
388 // Setup source manager structure
389 jpegSourceManager.init_source = initSource;
390 jpegSourceManager.fill_input_buffer = fillInputBuffer;
391 jpegSourceManager.skip_input_data = skipInputData;
392 jpegSourceManager.resync_to_restart = resyncToRestart;
393 jpegSourceManager.term_source = termSource;
394
395 // Set default source manager
396 jpegObject.src = &jpegSourceManager;
397
398 jpeg_read_header(&jpegObject, FALSE);
399
400 haveTables = 1;
401
402 return 0;
403}
404
405int
406Bitmap::buildFromZlibData(unsigned char *buffer, int width, int height, int format, int tableSize, int tableHasAlpha)
407{
408 z_streamstream;
409 int status;
410 unsigned char *data;
411 int elementSize;
412
413#if PRINT&1
414 printf("flash: loading with zlib\n");
415#endif
416
417 this->width = width;
418 this->height = height;
419 this->bpl = width;
420
421 if (tableHasAlpha) {
422 elementSize = 4;// Cmap is RGBA
423 } else {
424 elementSize = 3;// Cmap is RGB
425 }
426
427 stream.next_in = buffer;
428 stream.avail_in = 1;
429 stream.zalloc = Z_NULL;
430 stream.zfree = Z_NULL;
431
432 tableSize++;
433
434 // Uncompress Color Table
435 if (format == 3) {
436 unsigned char *colorTable;
437 long n;
438
439 // Ajust width for 32 bit padding
440 width = (width+3)/4*4;
441 this->width = width;
442 this->bpl = width;
443
444 depth = 1;
445 colorTable = new unsigned char[tableSize*elementSize];
446 if (colorTable == NULL) {
447 return -1;
448 }
449
450 stream.next_out = colorTable;
451 stream.avail_out = tableSize*elementSize;
452
453 inflateInit(&stream);
454
455 while (1) {
456 status = inflate(&stream, Z_SYNC_FLUSH);
457 if (status == Z_STREAM_END) {
458 break;
459 }
460 if (status != Z_OK) {
461 printf("Zlib cmap error : %s\n", stream.msg);
462 return -1;
463 }
464 stream.avail_in = 1;
465 // Colormap if full
466 if (stream.avail_out == 0) {
467 break;
468 }
469 }
470
471 nbColors = tableSize;
472
473 colormap = new Color[nbColors];
474 if (colormap == NULL) {
475 delete colorTable;
476 return -1;
477 }
478
479 for(n=0; n < nbColors; n++) {
480 colormap[n].red = colorTable[n*elementSize+0];
481 colormap[n].green = colorTable[n*elementSize+1];
482 colormap[n].blue = colorTable[n*elementSize+2];
483 if (tableHasAlpha) {
484 colormap[n].alpha = colorTable[n*elementSize+3];
485 }
486 }
487
488 delete colorTable;
489
490 } else if (format == 4) {
491 depth = 2;
492 width = (width+1)/2*2;
493 this->bpl = width;
494 } else if (format == 5) {
495 depth = 4;
496 }
497
498 data = new unsigned char[depth*width*height];
499 if (data == NULL) {
500 if (colormap) delete colormap;
501 return -1;
502 }
503
504 stream.next_out = data;
505 stream.avail_out = depth*width*height;
506
507 if (format != 3) {
508 status = inflateInit(&stream);
509 }
510
511 while (1) {
512 status = inflate(&stream, Z_SYNC_FLUSH) ;
513 if (status == Z_STREAM_END) {
514 break;
515 }
516 if (status != Z_OK) {
517 printf("Zlib data error : %s\n", stream.msg);
518 delete data;
519 return -1;
520 }
521 stream.avail_in = 1;
522 }
523
524 inflateEnd(&stream);
525
526 pixels = new unsigned char [height*width];
527 if (pixels == NULL) {
528 if (colormap) delete colormap;
529 delete data;
530 return -1;
531 }
532
533 if (format != 3) {
534 int n,c;
535 unsigned char r,g,b,a;
536 unsigned char *ptr;
537
538 r = g = b = a = 0; /* to supress warnings */
539
540 nbColors = 0;
541 colormap = new Color[256];
542 if (colormap == NULL) {
543 delete data;
544 delete pixels;
545 return -1;
546 }
547 memset(colormap, 0, 256 * sizeof(Color));
548 ptr = pixels;
549
550 for(n=0; n < width*height*depth; n+=depth,ptr++) {
551
552 switch (format) {
553 case 4:
554 a = 1;
555 r = (data[n] & 0x78)<<1;
556 g = ((data[n] & 0x03)<<6) | (data[n+1] & 0xc0)>>2;
557 b = (data[n+1] & 0x1e)<<3;
558 break;
559 case 5:
560 a = data[n];
561 // Reduce color dynamic range
562 r = data[n+1]&0xe0;
563 g = data[n+2]&0xe0;
564 b = data[n+3]&0xe0;
565 break;
566 }
567 for(c=0; c < nbColors; c++) {
568 if (r == colormap[c].red
569 && g == colormap[c].green
570 && b == colormap[c].blue) {
571 *ptr = c;
572 break;
573 }
574 }
575 if (c == nbColors) {
576 if (nbColors == 256) continue;
577 nbColors++;
578 if (nbColors == 256) {
579 //printf("Colormap entries exhausted. After %d scanned pixels\n", n/4);
580 }
581 colormap[c].alpha = a;
582 colormap[c].red = r;
583 colormap[c].green = g;
584 colormap[c].blue = b;
585 *ptr = c;
586 }
587 }
588 } else {
589 memcpy(pixels, data, width*height);
590 if (tableHasAlpha) {
591 int n;
592 unsigned char *ptr, *alpha;
593
594 alpha_buf = (unsigned char *)malloc(width*height);
595 ptr = data;
596 alpha = alpha_buf;
597 for(n=0; n < width*height; n++, ptr++, alpha++) {
598 *alpha = colormap[*ptr].alpha;
599 }
600 }
601 }
602
603 delete data;
604 return 0;
605}
606