OSDN Git Service

test for replaceBitmapData Lossless with alpha0
[swfed/swfed.git] / src / bitmap_util.c
1 /*
2   gcc -W -Wall -D__BITMAP_UTIL_DEBUG__ bitmap_util.c jpeg_segment.c bitstream.c
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h> // strncmp
8 #include "jpeg_segment.h"
9 #include "bitmap_util.h"
10
11 #define isJPEG_DHT(c) ((c) == 0xC4)
12 #define isJPEG_JPG(c) ((c) == 0xC8)
13 #define isJPEG_DAC(c) ((c) == 0xCC)
14
15 #define isJPEG_SOFXX(c) ((0xC0 <= c) && (c <= 0xCF) && (!isJPEG_DHT(c)) && (!isJPEG_JPG(c)) && (!isJPEG_DAC(c)))
16
17 int jpeg_size_segment(jpeg_segment_t *jpeg_seg, int *width, int *height) {
18     jpeg_segment_node_t *node;
19     for (node = jpeg_seg->head ; node ; node = node->next) {
20         register int marker = node->marker;
21         if (isJPEG_SOFXX(marker)) {
22             *width  = 0x100 * node->data_ref[3] + node->data_ref[4];
23             *height = 0x100 * node->data_ref[1] + node->data_ref[2];
24             return 0; // found
25         }
26     }
27     return 1; // not found
28 }
29
30 int jpeg_size(unsigned char *data, unsigned long data_len,
31               int *width, int *height) {
32     unsigned int idx, chunk_length = 0;
33     int marker1, marker2;
34     for (idx = 0 ; ((idx + 8) < data_len) && ((marker1 = data[idx]) == 0xFF);
35          idx += chunk_length) {
36         marker2 = data[idx + 1];
37         switch (marker2) {
38           case 0xD8: // SOI (Start of Image)
39           case 0xD9: // EOI (End of Image)
40               chunk_length = 2;
41               break;
42           case 0xDA: // SOS
43               return 1; // not found
44           default:
45             if (isJPEG_SOFXX(marker2)) {
46                 *width  = 0x100 * data[idx + 7] + data[idx + 8];
47                 *height = 0x100 * data[idx + 5] + data[idx + 6];
48                 return 0; // success
49             }
50             chunk_length = 0x100 * data[idx + 2] + data[idx + 3] + 2;
51             break;
52         }
53         if (chunk_length == 0) { // fail safe;
54             break;
55         }
56     }
57     return 1; // ng
58 }
59
60 int
61 png_size(unsigned char *data, unsigned long data_len,
62          int *width, int *height) {
63     if (data_len < 24) {
64         fprintf(stderr, "png_size: data_len(%lu) < 16\n", data_len);
65         return 1;
66     }
67     *width = (((data[16]*0x100) + data[17])*0x100 + data[18])*0x100 + data[19];
68     *height =(((data[20]*0x100) + data[21])*0x100 + data[22])*0x100 + data[23];
69     return 0;
70 }
71
72 int
73 gif_size(unsigned char *data, unsigned long data_len,
74                     int *width, int *height) {
75     if (data_len < 10) {
76         fprintf(stderr, "gif_size: data_len(%lu) < 10\n", data_len);
77         return 1;
78     }
79     *width  = 0x100 * data[7] + data[6];
80     *height = 0x100 * data[9] + data[8];
81     return 0;
82 }
83
84 int
85 detect_bitmap_format(unsigned char *data, unsigned long data_len) {
86     if (data_len < 4) {
87         return BITMAP_UTIL_FORMAT_UNKNOWN; // too short
88     }
89     if (strncmp((const char*)data, "\xff\xd8\xff", 3) == 0) {
90         return BITMAP_UTIL_FORMAT_JPEG;
91     } else if (strncmp((const char*)data + 1, "PNG", 3) == 0) {
92         return BITMAP_UTIL_FORMAT_PNG;
93     } else if (strncmp((const char*)data, "GIF", 3) == 0) {
94         return BITMAP_UTIL_FORMAT_GIF;
95     }
96     return BITMAP_UTIL_FORMAT_UNKNOWN;
97 }
98
99 int
100 bitmap_size(unsigned char *data, unsigned long data_len,
101                     int *width, int *height) {
102     int format = detect_bitmap_format(data, data_len);
103     switch (format) {
104     case BITMAP_UTIL_FORMAT_JPEG:
105         return jpeg_size(data, data_len, width, height);
106     case BITMAP_UTIL_FORMAT_PNG:
107         return png_size(data, data_len, width, height);
108     case BITMAP_UTIL_FORMAT_GIF:
109         return gif_size(data, data_len, width, height);
110     }
111     fprintf(stderr, "bitmap_size: illegal format\n");
112     return 1;
113 }
114
115
116 #ifdef __BITMAP_UTIL_DEBUG__  /* for component debug */
117
118 #include <sys/stat.h>
119
120 int main(int argc, char **argv) {
121     char *filename;
122     struct stat sbuf;
123     FILE *fp = NULL;
124     unsigned char *data;
125     unsigned long data_len;
126     int width = 0, height = 0;
127     int ret;
128     int i;
129     if (argc < 2) {
130         fprintf(stderr, "Usage: %s <bitmap_file> [<bitmap_file2> [...]]\n", argv[0]);
131         return EXIT_FAILURE;
132     }
133     for (i = 1 ; i < argc ; i++) {
134         int bitmap_format;
135         filename = argv[i];
136         if (stat(filename, &sbuf)) {
137             fprintf(stderr, "Can't stat file(%s)\n", filename);
138             return EXIT_FAILURE;
139         }
140         data_len = sbuf.st_size;
141         fp = fopen(filename, "rb");
142         if (fp == NULL) {
143             fprintf(stderr, "Can't open infile(%s)\n", filename);
144             return EXIT_FAILURE;
145         }
146         data = malloc(data_len);
147         if (fread(data, 1, data_len, fp) != data_len) {
148             fclose(fp);
149             return 1;
150         }
151         fclose(fp);
152         bitmap_format = detect_bitmap_format(data, data_len);
153         switch (bitmap_format) {
154         case BITMAP_UTIL_FORMAT_JPEG:
155             printf("JPEG\n");
156             ret = jpeg_size(data, data_len, &width, &height);
157             break;
158         case BITMAP_UTIL_FORMAT_PNG:
159             printf("PNG\n");
160             ret = png_size(data, data_len, &width, &height);
161             break;
162         case BITMAP_UTIL_FORMAT_GIF:
163             printf("GIF\n");
164             ret = gif_size(data, data_len, &width, &height);
165             break;
166         default:
167             fprintf(stderr, "unknown format (%s)\n", filename);
168             exit(0);
169         }
170         free(data);
171         if (ret) {
172             fprintf(stderr, "Can't get bitmap size(%s)\n", filename);
173             return EXIT_FAILURE;
174         }
175         printf("width=%d height=%d\n", width, height);
176     }
177     return EXIT_SUCCESS;
178 }
179
180 #endif /* __BITMAP_UTIL_DEBUG__ */