-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathconvert-uncompressed-image-header.c
126 lines (113 loc) · 3.79 KB
/
convert-uncompressed-image-header.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "ntrcom/nitrocompression.h"
#include "phoenixgfx.h"
#include "lodepng/lodepng.h"
#define BREAK(x) { printf(x); return 1; }
typedef struct {
unsigned char magic[4];
uint32_t headerSize;
uint32_t imageSize;
uint32_t paletteOffset;
uint32_t paletteSize;
}__attribute__((packed)) controlHeader;
/* these files seem to be based around the common nitro BTX0/NSBTX format... */
int main( int argc, char** argv ) {
if ( argc < 6 )
{
printf( "Not enough arguments given!\nUsage: %s [infile] [outfile] [offset in hex] [pixelsX] [pixelsY] [transparency] [alpha override]\nnote that the pixelsX and pixelsY arguments are for fallback purposes only, the sizes are usually in the file\nalpha override is optional, pass the number of non alpha pixels in hex (works only with 8bpp!)\n", argv[0] );
return 1;
}
unsigned int i, transparency, pixelsX, pixelsY, bpp, alphaover;
pixelsX = strtoul(argv[3], NULL, 10);
pixelsY = strtoul(argv[4], NULL, 10);
transparency = strtoul(argv[5], NULL, 10);
if(argc == 7) alphaover = strtoul(argv[6], NULL, 16);
unsigned char *workbuffer = NULL, *rgbaPixelData = NULL, *paletteData = NULL;
controlHeader header;
FILE *f;
if( !(f = fopen( argv[1], "rb" ))) {
printf("Couldnt open file %s\n", argv[1]);
return 1;
}
fread( &header, 0x14, 1, f );
if( header.magic[1] > 5 ) printf("evil width %x in file\n", header.magic[1]);
else {
pixelsX = 8 << header.magic[1];
printf("read tex width is %04d\n", pixelsX);
}
if( header.magic[2] > 5 ) printf("evil height %x in file\n", header.magic[2]);
else {
pixelsY = 8 << header.magic[2];
printf("read tex height is %04d\n", pixelsY);
}
/* byte 0 is the texture type, refer to GBATEK->DS 3D Texture Formats for details */
switch( header.magic[0] ) {
/* 4bpp */
case 3: {
printf("image is 4bpp\n");
bpp = image4bpp;
if((header.imageSize) != ((pixelsX*pixelsY)/2)) BREAK("size doesnt match!\n");
break;
}
/* 8bpp */
case 4: {
printf("image is 8bpp\n");
bpp = image8bpp;
if((header.imageSize) != ((pixelsX*pixelsY))) BREAK("size doesnt match!\n");
break;
}
/* a5i3 */
case 6: {
printf("image is a5i3\n");
bpp = imagea5i3;
if((header.imageSize) != ((pixelsX*pixelsY))) BREAK("size doesnt match!\n");
break;
}
/* fallback */
default: {
printf("fallback. textype is %08x\n", header.magic[0]);
if( header.paletteSize < 0x200 ) {
printf("image is 4bpp\n");
bpp = image4bpp;
if((header.imageSize) != ((pixelsX*pixelsY)/2)) BREAK("size doesnt match!\n");
}
else {
printf("image is 8bpp\n");
bpp = image8bpp;
if((header.imageSize) != ((pixelsX*pixelsY))) BREAK("size doesnt match!\n");
}
break;
}
}
if( alphaover && !image8bpp ) BREAK("alphaover only works with 8bpp images!\n");
if( bpp == imagea5i3 ) {
if( header.paletteSize == 0x200 ) paletteData = malloc(header.paletteSize);
else {
paletteData = malloc(8*2);
memset(paletteData, 0, 8*2);
}
}
else if ( bpp == imagea3i5 ) {
paletteData = malloc(32*2);
memset(paletteData, 0, 32*2);
}
else paletteData = malloc(header.paletteSize);
fseek( f, header.paletteOffset, SEEK_SET );
fread( paletteData, header.paletteSize, 1, f );
fseek( f, header.headerSize, SEEK_SET );
workbuffer = malloc(header.imageSize);
fread( workbuffer, header.imageSize, 1, f );
if( alphaover ) for( i = alphaover; i < header.imageSize; i++ ) workbuffer[i] = 0;
rgbaPixelData = linearImageWithPaletteToRGBA(workbuffer, paletteData, pixelsX, pixelsY, bpp, transparency);
lodepng_encode32_file( argv[2], rgbaPixelData, pixelsX, pixelsY );
free( workbuffer );
free( rgbaPixelData );
free( paletteData );
printf("total size of image %08x\n", header.paletteOffset + header.paletteSize);
printf("Done.\n");
fclose(f);
return 0;
}