Subversion Repositories Kolibri OS

Rev

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    ...\n");
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
}