View difference between Paste ID: GJNGa77L and gUpEP6JD
SHOW: | | - or go back to the newest paste.
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <stdint.h>
4
#include <string.h>
5
6
uint8_t *compressed;
7
int xrows;
8
int xwidth;
9
int curbit;
10
int curbyte;
11-
void writebit(bit)
11+
12
void writebit(int bit)
13
{
14
	if(++curbit == 8)
15
	{
16
		curbyte++;
17
		curbit = 0;
18-
	compressed[curbyte] |= bit << 7 - curbit;
18+
19
	compressed[curbyte] |= bit << (7 - curbit);
20
}
21
22
void method_1(uint8_t *RAM)
23
{
24
	int i;
25
	int j;
26
	int nibble_1;
27
	int nibble_2;
28
	int code_1;
29
	int code_2;
30
	int table;
31
	static int method_1[2][0x10] = {{0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, 0xC, 0xD, 0xF, 0xE, 0xA, 0xB, 0x9, 0x8}, {0x8, 0x9, 0xB, 0xA, 0xE, 0xF, 0xD, 0xC, 0x4, 0x5, 0x7, 0x6, 0x2, 0x3, 0x1, 0x0}};
32
33
	for(i = 0; i < xrows * xwidth * 8; i++)
34
	{
35
		j = i / xrows;
36
		j += i % xrows * xwidth * 8;
37
		if(!(i % xrows))
38
		{
39
			nibble_2 = 0;
40
		}
41
		nibble_1 = (RAM[j] >> 4) & 0x0F;
42
		table = 0;
43
		if(nibble_2 & 1)
44
		{
45
			table = 1;
46
		}
47
		code_1 = method_1[table][nibble_1];
48
		nibble_2 = RAM[j] & 0x0F;
49
		table = 0;
50
		if(nibble_1 & 1)
51
		{
52
			table = 1;
53
		}
54
		code_2 = method_1[table][nibble_2];
55
		RAM[j] = (code_1 << 4) | code_2;
56
	}
57
}
58
59
void RLE(int nums)
60
{
61
	int search;
62
	int i;
63
	int j;
64
	int bitcount;
65-
	static int RLE[0x10] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
65+
66
	static unsigned int RLE[0x10] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
67
68
	bitcount = -1;
69
	search = ++nums;
70
	while(search > 0)
71
	{
72
		for(i = 0; i < 0xF; i++)
73
		{
74
			if(RLE[i] == search)
75
			{
76
				bitcount = i;
77
				break;
78
			}
79
		}
80
		if(bitcount != -1)
81
		{
82
			break;
83
		}
84
		search--;
85
	}
86
	number = nums - RLE[bitcount];
87
	for(j = 0; j < bitcount; j++)
88
	{
89
		writebit(1);
90
	}
91
	writebit(0);
92
	for(j = bitcount; j >= 0; j--)
93
	{
94
		writebit((number >> j) & 1);
95
	}
96
}
97
98
void data_packet(uint8_t *bitgroups, int bgi)
99
{
100
	int i;
101
	for(i = 0; i < bgi; i++)
102
	{
103
		writebit((bitgroups[i] >> 1) & 1);
104
		writebit(bitgroups[i] & 1);
105
	}
106
}
107
108
int interpret_compress(uint8_t *RAM_1, uint8_t *RAM_2, int interpretation, int switchram)
109
{
110
	uint8_t *_1_RAM;
111
	uint8_t *_2_RAM;
112
	int i;
113
	int ram;
114
	int type;
115
	int nums;
116
	uint8_t *bitgroups;
117
	int byte;
118
	int bit;
119
	int bitgroup;
120
	int bgi = 0;
121
122
	_1_RAM = (uint8_t*) calloc(0x188, 1);
123
	_2_RAM = (uint8_t*) calloc(0x188, 1);
124
	if(switchram)
125
	{
126
		memcpy(_1_RAM, RAM_2, 0x188);
127
		memcpy(_2_RAM, RAM_1, 0x188);
128
	}
129
	else
130
	{
131
		memcpy(_1_RAM, RAM_1, 0x188);
132
		memcpy(_2_RAM, RAM_2, 0x188);
133
	}
134
135
	switch(interpretation)
136
	{
137
		case 1:
138
			method_1(_1_RAM);
139
			method_1(_2_RAM);
140
		break;
141
		case 2:
142
		case 3:
143
			for(i = 0; i < xrows * xwidth * 8; i++)
144
			{
145
				_2_RAM[i] ^= _1_RAM[i];
146
			}
147
			method_1(_1_RAM);
148
		break;
149
	}
150
	if(interpretation == 3)
151
	{
152
		method_1(_2_RAM);
153
	}
154
155
	curbit = 7;
156
	curbyte = 0;
157
	compressed = (uint8_t*) calloc(0x310, 1);
158
	compressed[0] = (xrows << 4) | xwidth;
159
	writebit(switchram);
160
161
	for(ram = 0; ram < 2; ram++)
162
	{
163
		type = 0;
164
		nums = 0;
165
		bitgroups = (uint8_t*) calloc(0x1000, 1);
166
		for(i = 0; i < xrows * xwidth * 32; i++)
167
		{
168
			byte = i / (xwidth * 32);
169
			byte = byte * xwidth * 8 + i % (xwidth * 8);
170
			bit = i / (xwidth * 8);
171
			bit = (bit * 2) % 8;
172
			if(ram)
173
			{
174
				bitgroup = (_2_RAM[byte] >> (6 - bit)) & 3;
175-
				bitgroup = (_2_RAM[byte] >> 6 - bit) & 3;
175+
176
			else
177
			{
178
				bitgroup = (_1_RAM[byte] >> (6 - bit)) & 3;
179-
				bitgroup = (_1_RAM[byte] >> 6 - bit) & 3;
179+
180
			if(!bitgroup)
181
			{
182
				if(!type)
183
				{
184
					writebit(0);
185
				}
186
				else if(type == 1)
187
				{
188
					nums++;
189
				}
190
				else
191
				{
192
					data_packet(bitgroups, bgi);
193
					writebit(0);
194
					writebit(0);
195
				}
196
				type = 1;
197
				free(bitgroups);
198
				bitgroups = (uint8_t*) calloc(0x1000, 1);
199
				bgi = 0;
200
			}
201
			else
202
			{
203
				if(!type)
204
				{
205
					writebit(1);
206
				}
207
				else if(type == 1)
208
				{
209
					RLE(nums);
210
				}
211
				type = -1;
212
				bitgroups[bgi++] = bitgroup;
213
				nums = 0;
214
			}
215
		}
216
		if(type == 1)
217
		{
218
			RLE(nums);
219
		}
220
		else
221
		{
222
			data_packet(bitgroups, bgi);
223
		}
224
		if(!ram)
225
		{
226
			if(interpretation < 2)
227
			{
228
				writebit(0);
229
			}
230
			else
231
			{
232
				writebit(1);
233
				writebit(interpretation - 2);
234
			}
235
		}
236
	}
237
	free(bitgroups);
238
	free(_1_RAM);
239
	free(_2_RAM);
240
	return curbyte + 1;
241
}
242
243
int compress(uint8_t *data, int width, int height)
244
{
245
	uint8_t *RAM_1;
246
	uint8_t *RAM_2;
247
	int i;
248
	int newsize;
249
	int size = -1;
250
	uint8_t *current = NULL;
251
252
	xrows = height;
253
	xwidth = width;
254
255
	RAM_1 = (uint8_t*) calloc(0x188, 1);
256
	RAM_2 = (uint8_t*) calloc(0x188, 1);
257
258
	for(i = 0; i < xrows * xwidth * 8; i++)
259
	{
260
		RAM_1[i] = data[(i << 1)];
261
		RAM_2[i] = data[(i << 1) | 1];
262
	}
263
264
	for(i = 0; i < 6; i++)
265
	{
266
		newsize = interpret_compress(RAM_1, RAM_2, i / 2 + 1, i % 2);
267
		if(size == -1 || newsize < size)
268
		{
269
			if(current != NULL)
270
			{
271
				free(current);
272
			}
273
			current = (uint8_t*) calloc(0x310, 1);
274
			memcpy(current, compressed, newsize);
275
			free(compressed);
276
			size = newsize;
277
		}
278
	}
279
	compressed = (uint8_t*) calloc(0x310, 1);
280
	memcpy(compressed, current, size);
281
	free(current);
282
283
	free(RAM_1);
284
	free(RAM_2);
285
286
	return size;
287
}
288
289
int main(int argc, char *argv[])
290
{
291
	FILE *f;
292
	int fz;
293
	int size;
294
	uint8_t *contents;
295
	int tiles;
296
297-
		fputs("Usage: pkmncompress infile.2bpp outfile.bin\n", stderr);
297+
298
	{
299
		printf("Usage: pkmncompress infile.2bpp outfile.bin\n");
300
		/*fputs("Usage: pkmncompress infile.2bpp outfile.bin\n", stderr);*/
301
		return EXIT_FAILURE;
302
	}
303
304
	f = fopen(argv[1], "rb");
305
306
	if(!f)
307
	{
308
		perror("Opening file failed");
309
		return EXIT_FAILURE;
310
	}
311-
	if(fz > 0x310)
311+
312
	fseek(f, 0, SEEK_END);
313-
		fputs("Error: file too large.\n", stderr);
313+
314
	if(fz == 0x310)
315
	{
316
		tiles = 7;
317
	}
318
	else if(fz == 0x240)
319
	{
320
		tiles = 6;
321
	}
322-
	size = compress(contents, 7, 7);
322+
	else if(fz == 0x190)
323
	{
324
		tiles = 5;
325
	}
326
	else if(fz == 0x100)
327
	{
328
		tiles = 4;
329
	}
330
	else
331
	{
332
		printf("Error: wrong file size.\n");
333
		/*fputs("Error: wrong file size.\n", stderr);*/
334
		return EXIT_FAILURE;
335
	}
336
337
	contents = (uint8_t*) calloc(0x310, 1);
338
	fseek(f, 0, SEEK_SET);
339
	fread(contents, 1, fz, f);
340
	fclose(f);
341
342
	size = compress(contents, tiles, tiles);
343
344
	free(contents);
345
346
	f = fopen(argv[2], "wb");
347
	fwrite(compressed, 1, size, f);
348
349
	free(compressed);
350
351
	printf("Success! File size: %i bytes\n", size);
352
353
	return EXIT_SUCCESS;
354
}