2 gcc -W -Wall -D__BITMAP_UTIL_DEBUG__ bitmap_util.c jpeg_segment.c bitstream.c
7 #include <string.h> // strncmp
8 #include "jpeg_segment.h"
9 #include "bitmap_util.h"
11 #define isJPEG_DHT(c) ((c) == 0xC4)
12 #define isJPEG_JPG(c) ((c) == 0xC8)
13 #define isJPEG_DAC(c) ((c) == 0xCC)
15 #define isJPEG_SOFXX(c) ((0xC0 <= c) && (c <= 0xCF) && (!isJPEG_DHT(c)) && (!isJPEG_JPG(c)) && (!isJPEG_DAC(c)))
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];
27 return 1; // not found
30 int jpeg_size(unsigned char *data, unsigned long data_len,
31 int *width, int *height) {
32 unsigned int idx, chunk_length = 0;
34 for (idx = 0 ; ((idx + 8) < data_len) && ((marker1 = data[idx]) == 0xFF);
35 idx += chunk_length) {
36 marker2 = data[idx + 1];
38 case 0xD8: // SOI (Start of Image)
39 case 0xD9: // EOI (End of Image)
43 return 1; // not found
45 if (isJPEG_SOFXX(marker2)) {
46 *width = 0x100 * data[idx + 7] + data[idx + 8];
47 *height = 0x100 * data[idx + 5] + data[idx + 6];
50 chunk_length = 0x100 * data[idx + 2] + data[idx + 3] + 2;
53 if (chunk_length == 0) { // fail safe;
61 png_size(unsigned char *data, unsigned long data_len,
62 int *width, int *height) {
64 fprintf(stderr, "png_size: data_len(%lu) < 16\n", data_len);
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];
73 gif_size(unsigned char *data, unsigned long data_len,
74 int *width, int *height) {
76 fprintf(stderr, "gif_size: data_len(%lu) < 10\n", data_len);
79 *width = 0x100 * data[7] + data[6];
80 *height = 0x100 * data[9] + data[8];
85 detect_bitmap_format(unsigned char *data, unsigned long data_len) {
87 return BITMAP_UTIL_FORMAT_UNKNOWN; // too short
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;
96 return BITMAP_UTIL_FORMAT_UNKNOWN;
100 bitmap_size(unsigned char *data, unsigned long data_len,
101 int *width, int *height) {
102 int format = detect_bitmap_format(data, data_len);
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);
111 fprintf(stderr, "bitmap_size: illegal format\n");
116 #ifdef __BITMAP_UTIL_DEBUG__ /* for component debug */
118 #include <sys/stat.h>
120 int main(int argc, char **argv) {
125 unsigned long data_len;
126 int width = 0, height = 0;
130 fprintf(stderr, "Usage: %s <bitmap_file> [<bitmap_file2> [...]]\n", argv[0]);
133 for (i = 1 ; i < argc ; i++) {
136 if (stat(filename, &sbuf)) {
137 fprintf(stderr, "Can't stat file(%s)\n", filename);
140 data_len = sbuf.st_size;
141 fp = fopen(filename, "rb");
143 fprintf(stderr, "Can't open infile(%s)\n", filename);
146 data = malloc(data_len);
147 if (fread(data, 1, data_len, fp) != data_len) {
152 bitmap_format = detect_bitmap_format(data, data_len);
153 switch (bitmap_format) {
154 case BITMAP_UTIL_FORMAT_JPEG:
156 ret = jpeg_size(data, data_len, &width, &height);
158 case BITMAP_UTIL_FORMAT_PNG:
160 ret = png_size(data, data_len, &width, &height);
162 case BITMAP_UTIL_FORMAT_GIF:
164 ret = gif_size(data, data_len, &width, &height);
167 fprintf(stderr, "unknown format (%s)\n", filename);
172 fprintf(stderr, "Can't get bitmap size(%s)\n", filename);
175 printf("width=%d height=%d\n", width, height);
180 #endif /* __BITMAP_UTIL_DEBUG__ */