honey

very old unfinished project. tracking so i dont lose it
git clone git://moonbender.net/honey
Log | Files | Refs | README

ppmtoc.c (6052B)


      1 #include <stdlib.h>
      2 #include <stdint.h>
      3 #include <stdio.h>
      4 #include <unistd.h>
      5 #include <fcntl.h>
      6 
      7 typedef struct
      8 {
      9 	uint32_t x, y;
     10 } vec2;
     11 
     12 typedef struct
     13 {
     14 	vec2 dimensions;
     15 	uint32_t datasize, bitdepth;
     16 	uint8_t *start;
     17 } imginfo;
     18 
     19 typedef struct
     20 {
     21 	uint32_t columns;
     22 	uint8_t *start;
     23 } palinfo;
     24 
     25 vec2 ParseDimensions(uint8_t *begin, uint32_t length)
     26 {
     27 	vec2 ret;
     28 	ret.x = ret.y = 0;
     29 	uint8_t xd = 0;
     30 	for (uint8_t i = 0; i < length; ++i)
     31 	{
     32 		if (*(begin + i) == ' ')
     33 		{
     34 			xd = 1;
     35 			continue;
     36 		}
     37 
     38 		if (xd)
     39 		{
     40 			ret.y = ret.y * 10;
     41 			ret.y += *(begin + i) - '0';
     42 		}
     43 		else
     44 		{
     45 			ret.x = ret.x * 10;
     46 			ret.x += *(begin + i) - '0';
     47 		}
     48 	}
     49 	return ret;
     50 }
     51 
     52 uint32_t ParseBitDepth(uint8_t *begin, uint32_t length)
     53 {
     54 	uint32_t depth = 0;
     55 	for (uint32_t i = 0; i < length; ++i)
     56 	{
     57 		depth = depth * 10;
     58 		depth += *(begin + i) - '0';
     59 	}
     60 	return depth;
     61 }
     62 
     63 
     64 /*	Parse the image header
     65 	ppm files begin with the identifying string P6
     66 	Next is the image dimensions on one line separated by a space
     67 	And finally the bit depth
     68 	We need all of this for error handling
     69 	Comments can appear at any point
     70 */
     71 imginfo ParseImgInfo(uint8_t *filedata, uint32_t size)
     72 {
     73 	imginfo ret;
     74 	ret.dimensions.x = 0;
     75 	ret.dimensions.y = 0;
     76 	ret.datasize = size;
     77 	uint32_t curs = 0;
     78 
     79 	uint8_t *line_start;
     80 	uint8_t pmode;
     81 	line_start = filedata;
     82 
     83 	//chop it up into lines and parse
     84 	while (1)
     85 	{
     86 		while (*(line_start + curs) != '\n')
     87 		{
     88 			curs++;
     89 			ret.datasize--;
     90 		}
     91 
     92 		if (*line_start == '#')
     93 		{
     94 			line_start += (curs + 1);
     95 			curs = 0;
     96 			continue;
     97 		}
     98 
     99 		if (pmode == 0) //first line, file identifier
    100 		{
    101 			if (!(*line_start == 'P' && *(line_start + 1) == '6'))
    102 			{
    103 				//ain't no ppm!
    104 				fprintf(stdout, "Invalid image file\n");
    105 				exit(0);
    106 			}
    107 			pmode = 1;
    108 		}
    109 		else if (pmode == 1) //second line, dimensions
    110 		{
    111 			ret.dimensions = ParseDimensions(line_start, curs);
    112 			pmode = 2;
    113 		}
    114 		else if (pmode == 2) //third line, bit depth
    115 		{
    116 			ret.bitdepth = ParseBitDepth(line_start, curs);
    117 			if (ret.bitdepth != 255)
    118 			{
    119 				fprintf(stdout, "Can't support bitdepth other than 255\n");
    120 				exit(0);
    121 			}
    122 
    123 			//24 bit colors, datasize can be determined by dimensions
    124 			ret.datasize = ret.dimensions.x * ret.dimensions.y * 3; //3 bytes
    125 			ret.start = (line_start + curs + 1);
    126 			return ret;
    127 		}
    128 		else
    129 		{
    130 			break;
    131 		}
    132 
    133 		line_start += (curs + 1);	
    134 		curs = 0;
    135 	}
    136 	fprintf(stdout, "Error loading image file");
    137 	exit(0);
    138 }
    139 
    140 void ParseImgData(uint32_t* clist, imginfo finfo)
    141 {
    142 	uint32_t curs = 0;
    143 	for (uint32_t i = 0; i < (finfo.datasize / 3); ++i)
    144 	{
    145 		*(clist + i) = 0;
    146 		for (int i2 = 0; i2 < 3; i2++)
    147 		{
    148 			*(clist + i) |= *(finfo.start + curs) << ((2 - i2) * 8);
    149 			curs++;
    150 		}
    151 	}
    152 }
    153 
    154 //TODO: write the function lol
    155 //Just need to do this and fix the ParsePalette function
    156 //to use the incoming info struct
    157 /* Parse the palette header
    158 begins with identifying string "GIMP Palette"
    159 Next is the name of the palette ("Name: thename")
    160 then the amount of columns ("Columns: number")
    161 the column amount is the only real important data */
    162 palinfo ParsePalHeader(uint8_t *filedata)
    163 {
    164 	palinfo ret;
    165 	ret.columns = 0;
    166 	ret.start = filedata;
    167 	ret.datasize = 0;
    168 	return ret;
    169 }
    170 
    171 //can only parse 16 column palettes for now
    172 void ParsePalette(uint32_t *clist, uint8_t *filedata, palinfo info)
    173 {
    174 	uint32_t curs = 0;
    175 	for (int i = 0; i < 16; ++i) 
    176 	{
    177 		*(clist + i) = 0;
    178 		uint8_t offs = 16;
    179 		uint8_t num = 0;
    180 		//parse line by line
    181 		while(1)
    182 		{
    183 			if (*(filedata + curs) == '\n')
    184 			{
    185 				*(clist + i) |= num;
    186 				break;
    187 			}
    188 			else if (*(filedata + curs) == ' ' && num)
    189 			{
    190 				*(clist + i) |= num << offs;
    191 				num = 0;
    192 				offs = 8;
    193 			}
    194 			else if (*(filedata + curs) != ' ')
    195 			{
    196 				num *= 10;
    197 				num += *(filedata + curs) - '0';	
    198 			}
    199 			curs++;
    200 		}
    201 		curs++;
    202 //		fprintf (stdout, "%x | curs: %d\n", *(clist + i), curs);
    203 	}
    204 }
    205 
    206 //print the image to stdout as an indexed .c array 
    207 void OutputIndexed(uint32_t *colors, uint32_t *pixels, imginfo *finfo)
    208 {
    209 	fprintf(stdout, "#include <stdint.h>\n");
    210 	fprintf(stdout, "static const uint8_t spritedata[%d] = \n{\n    ", (finfo->datasize / 3));
    211 
    212 	for (uint32_t i = 0; i < (finfo->datasize / 3); ++i)
    213 	{
    214 		uint8_t index = 0;
    215 		for (int i2 = 0; i2 < 11; ++i2)
    216 		{
    217 			if (*(pixels + i) == *(colors + i2))
    218 			{
    219 				index = i2;
    220 			}
    221 		}
    222 		fprintf(stdout, "%d", index);
    223 		if ( i != (finfo->datasize / 3) - 1)
    224 		{
    225 			fprintf(stdout, ", ");
    226 		}
    227 		if ( !((i + 1) % 10))
    228 		{
    229 			fprintf(stdout, "\n    ");
    230 		}
    231 	}
    232 	fprintf(stdout, "\n};\n");
    233 }
    234 
    235 
    236 int main(int argc, char *argv[])
    237 {
    238 	if (argc != 3)
    239 	{
    240 		fprintf(stdout, "Wrong number of arguments (%d).\n", argc);
    241 		fprintf(stdout, "Usage: ppmtoc image palette\n");
    242 		return -1;
    243 	}
    244 
    245 	char *fname_img = argv[1];
    246 //	char *fname_pal = argv[2];
    247 //	fprintf(stdout, "Arg 1: %s\n", (argv[1]));
    248 //	fprintf(stdout, "Arg 2: %s\n", (argv[2]));
    249 
    250 	int img = 0;
    251 	img = open(fname_img, O_RDONLY, 700);
    252 	if (img < 0)
    253 	{
    254 		fprintf(stdout, "%s : Couldn't open file\n", fname_img);
    255 		return -1;
    256 	}
    257 
    258 	uint8_t buffer[64000]; //this oughta be big enough!!
    259 	uint32_t pal_columns = 0;
    260 	int size;
    261 	size = read(img, &buffer, 64000);
    262 	close(img);
    263 
    264 	//parse image header
    265 	imginfo info = ParseImgInfo(&buffer[0], size);
    266 
    267 	fprintf(stdout, "// Width: %d\n", info.dimensions.x);
    268 	fprintf(stdout, "// Height: %d\n", info.dimensions.y);
    269 	fprintf(stdout, "// Datasize: %d\n", info.datasize);
    270 	fprintf(stdout, "// BitDepth: %d\n", info.bitdepth);
    271 
    272 /*
    273 	//load the image into an array of 32bit colors
    274 	uint32_t pixels[info.datasize / 3];
    275 	ParseImgData(&pixels[0], info);
    276 
    277 	//now open the palette file
    278 	int pal = 0;
    279 	pal = open(fname_pal, O_RDONLY, 700);
    280 	if (pal < 0)
    281 	{
    282 		fprintf(stdout, "%s : Couldn't open file\n", fname_pal);
    283 		return -1;
    284 	}
    285 	size = read(pal, &buffer, 64000);
    286 	close(pal);
    287 
    288 	//parse palette header
    289 	palinfo pinfo = ParsePalHeader(&buffer[0]);
    290 	uint32_t colors[pinfo.columns];
    291 
    292 	//now parse palette file
    293 	ParsePalette(&colors[0], &buffer[0], pinfo);
    294 
    295 	//compare the image data to the palette file and output
    296 	//an indexed image in a c array
    297 	OutputIndexed(&colors[0], &pixels[0], &info);
    298 */
    299 
    300 }