Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1805 | yogev_ezra | 1 | #include |
2 | #include |
||
3 | |||
4 | extern "C" __stdcall lzma_set_dict_size(unsigned logdictsize); |
||
5 | extern "C" __stdcall lzma_compress( |
||
6 | const void* source, |
||
7 | void* destination, |
||
8 | unsigned length, |
||
9 | void* workmem); |
||
10 | |||
11 | typedef struct |
||
12 | { |
||
13 | short int sizeX; |
||
14 | short int sizeY; |
||
15 | int compressedSize; |
||
16 | int physicalOffset; |
||
17 | int uncompressedSize; |
||
18 | } SCompBmpHeader; |
||
19 | |||
20 | int main(int argc, char* argv[]) |
||
21 | { |
||
22 | if (argc < 3) |
||
23 | { |
||
24 | printf("Usage: bmp2src |
||
25 | return 1; |
||
26 | } |
||
27 | FILE* fo = fopen(argv[1], "wb"); |
||
28 | if (!fo) |
||
29 | { |
||
30 | printf("Cannot create destination file\n"); |
||
31 | return 2; |
||
32 | } |
||
33 | int n=0; |
||
34 | SCompBmpHeader* hea = (SCompBmpHeader*)malloc((argc-2)*sizeof(SCompBmpHeader)); |
||
35 | void** ptrs = (void**)malloc((argc-2)*4); |
||
36 | lzma_set_dict_size(20); |
||
37 | void* workmem = (void*)malloc(0x509000 + (1<<20)*19/2); |
||
38 | for (int i=2;i |
||
39 | { |
||
40 | FILE* fi = fopen(argv[i], "rb"); |
||
41 | if (!fi) |
||
42 | { |
||
43 | printf("Cannot open input file %s\n",argv[i]); |
||
44 | continue; |
||
45 | } |
||
46 | unsigned char buf[0x36]; |
||
47 | fread(buf,1,0x36,fi); |
||
48 | if (buf[0] != 'B' || buf[1] != 'M') |
||
49 | { |
||
50 | if (buf[0] != 0xFF || buf[1] != 0xD8) |
||
51 | { |
||
52 | printf("%s: unrecognized type\n",argv[i]); |
||
53 | fclose(fi); |
||
54 | continue; |
||
55 | } |
||
56 | // JPEG |
||
57 | printf("Processing %s ...",argv[i]); |
||
58 | fseek(fi,0,SEEK_END); |
||
59 | unsigned insize = ftell(fi); |
||
60 | void* output = malloc(insize); |
||
61 | unsigned char* ptr = (unsigned char*)output; |
||
62 | *ptr++ = 0xFF; |
||
63 | *ptr++ = 0xD8; |
||
64 | // Now load JPEG file, skipping all APPx markers |
||
65 | fseek(fi,2,SEEK_SET); |
||
66 | bool bOk = false; |
||
67 | for (;;) |
||
68 | { |
||
69 | if (fread(buf,1,4,fi) != 4 || buf[0] != 0xFF) |
||
70 | { |
||
71 | printf("%s: invalid JPEG file\n",argv[i]); |
||
72 | bOk = false; |
||
73 | break; |
||
74 | } |
||
75 | // ignore APPx markers |
||
76 | if (buf[1] >= 0xE0 && buf[1] <= 0xEF) |
||
77 | { |
||
78 | fseek(fi,buf[2]*256 + buf[3] - 2,SEEK_CUR); |
||
79 | continue; |
||
80 | } |
||
81 | unsigned len = buf[2]*256 + buf[3] + 2; |
||
82 | fseek(fi,-4,SEEK_CUR); |
||
83 | fread(ptr,1,len,fi); |
||
84 | if (buf[1]>=0xC0 && buf[1]<=0xCF && buf[1]!=0xC4 && buf[1]!=0xC8 && buf[1]!=0xCC) |
||
85 | { |
||
86 | // found SOFn marker |
||
87 | hea[i-2].sizeX = (unsigned char)ptr[4+3]*256 + (unsigned char)ptr[4+4]; |
||
88 | hea[i-2].sizeY = (unsigned char)ptr[4+1]*256 + (unsigned char)ptr[4+2]; |
||
89 | bOk = true; |
||
90 | } |
||
91 | ptr += len; |
||
92 | if (buf[1] == 0xDA) |
||
93 | { |
||
94 | // SOS marker |
||
95 | len = insize - ftell(fi); |
||
96 | fread(ptr,1,len,fi); |
||
97 | ptr += len; |
||
98 | break; |
||
99 | } |
||
100 | } |
||
101 | if (!bOk) {printf(" invalid\n");free(ptr);continue;} |
||
102 | hea[i-2].compressedSize = ptr - (unsigned char*)output; |
||
103 | hea[i-2].uncompressedSize = hea[i-2].compressedSize - 1; |
||
104 | hea[i-2].physicalOffset = (i==2) ? 0 : |
||
105 | hea[i-3].physicalOffset+hea[i-3].compressedSize; |
||
106 | ptrs[i-2] = output; |
||
107 | ++n; |
||
108 | printf(" OK\n"); |
||
109 | continue; |
||
110 | } |
||
111 | if (buf[0x1C] != 24) |
||
112 | { |
||
113 | printf("Input file %s is not 24-bit BMP\n",argv[i]); |
||
114 | fclose(fi); |
||
115 | continue; |
||
116 | } |
||
117 | int width = *(int*)(buf+0x12); |
||
118 | int linesize = (width*3+3)&~3; |
||
119 | int height = *(int*)(buf+0x16); |
||
120 | void* input = malloc(width*height*3); |
||
121 | void* packed = malloc(9*width*height*3/8 + 0x80); |
||
122 | for (int p=0;p |
||
123 | { |
||
124 | fseek(fi,(height-p-1)*linesize+0x36,SEEK_SET); |
||
125 | fread((char*)input+p*width*3, 1, width*3, fi); |
||
126 | } |
||
127 | fclose(fi); |
||
128 | hea[i-2].sizeX = (short)width; |
||
129 | hea[i-2].sizeY = (short)height; |
||
130 | unsigned uncompressedSize = width*height*3; |
||
131 | hea[i-2].uncompressedSize = uncompressedSize; |
||
132 | hea[i-2].physicalOffset = (i==2) ? 0 : |
||
133 | hea[i-3].physicalOffset+hea[i-3].compressedSize; |
||
134 | printf("Compressing %s ...",argv[i]); |
||
135 | unsigned compressedSize = lzma_compress(input,packed, |
||
136 | uncompressedSize,workmem); |
||
137 | if (compressedSize >= uncompressedSize) |
||
138 | { |
||
139 | compressedSize = uncompressedSize; |
||
140 | free(packed); |
||
141 | ptrs[i-2] = input; |
||
142 | } |
||
143 | else |
||
144 | { |
||
145 | ptrs[i-2] = packed; |
||
146 | free(input); |
||
147 | } |
||
148 | printf(" %d -> %d\n",uncompressedSize, compressedSize); |
||
149 | hea[i-2].compressedSize = compressedSize; |
||
150 | ++n; |
||
151 | } |
||
152 | for (i=0;i |
||
153 | hea[i].physicalOffset += 4+n*sizeof(SCompBmpHeader); |
||
154 | fwrite(&n,4,1,fo); |
||
155 | fwrite(hea,sizeof(SCompBmpHeader),n,fo); |
||
156 | for (i=0;i |
||
157 | { |
||
158 | fwrite(ptrs[i],1,hea[i].compressedSize,fo); |
||
159 | free(ptrs[i]); |
||
160 | } |
||
161 | fclose(fo); |
||
162 | free(hea); |
||
163 | free(workmem); |
||
164 | free(ptrs); |
||
165 | return 0; |
||
166 | } |