1 #include <stdint.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include "shadowdive/error.h"
6 #include "shadowdive/palette.h"
7
sd_palette_create(sd_palette * pal)8 int sd_palette_create(sd_palette *pal) {
9 if(pal == NULL) {
10 return SD_INVALID_INPUT;
11 }
12 memset(pal, 0, sizeof(sd_palette));
13 return SD_SUCCESS;
14 }
15
sd_palette_free(sd_palette * pal)16 void sd_palette_free(sd_palette *pal) {}
17
sd_palette_resolve_color(uint8_t r,uint8_t g,uint8_t b,const sd_palette * pal)18 unsigned char sd_palette_resolve_color(uint8_t r, uint8_t g, uint8_t b, const sd_palette *pal) {
19 for(unsigned int i = 0; i < 256; i++) {
20 uint8_t red = pal->data[i][0] & 0xff;
21 uint8_t green = pal->data[i][1] & 0xff;
22 uint8_t blue = pal->data[i][2] & 0xff;
23 if(red == r && blue == b && green == g) {
24 return i;
25 }
26 }
27 return 0;
28 }
29
sd_palette_to_gimp_palette(const sd_palette * palette,const char * filename)30 int sd_palette_to_gimp_palette(const sd_palette *palette, const char *filename) {
31 sd_writer *w;
32 const unsigned char *d;
33 unsigned char r,g,b;
34 int i;
35
36 if(palette == NULL || filename == NULL) {
37 return SD_INVALID_INPUT;
38 }
39
40 if(!(w = sd_writer_open(filename))) {
41 return SD_FILE_OPEN_ERROR;
42 }
43
44 sd_write_fprintf(w, "GIMP Palette\n");
45 sd_write_fprintf(w, "Name: %s\n", filename);
46 sd_write_fprintf(w, "#\n");
47 for(i = 0; i < 255; i++) {
48 d = palette->data[i];
49 r = d[0] & 0xff;
50 g = d[1] & 0xff;
51 b = d[2] & 0xff;
52 sd_write_fprintf(w, "%3u %3u %3u\n", r, g, b);
53 }
54
55 sd_writer_close(w);
56 return SD_SUCCESS;
57 }
58
sd_palette_from_gimp_palette(sd_palette * palette,const char * filename)59 int sd_palette_from_gimp_palette(sd_palette *palette, const char *filename) {
60 sd_reader *rd;
61 char tmp[128];
62 int i;
63
64 if(palette == NULL || filename == NULL) {
65 return SD_INVALID_INPUT;
66 }
67
68 if(!(rd = sd_reader_open(filename))) {
69 return SD_FILE_OPEN_ERROR;
70 }
71
72 // Read and match header
73 if(!sd_match(rd, "GIMP Palette\n", 13)) {
74 sd_reader_close(rd);
75 return SD_FILE_INVALID_TYPE;
76 }
77 while(1) {
78 sd_read_line(rd, tmp, 128);
79 if(!sd_reader_ok(rd)) {
80 sd_reader_close(rd);
81 return SD_FILE_INVALID_TYPE;
82 }
83 if(tmp[0] == '#') {
84 break;
85 }
86 }
87
88 // Read data
89 for(i = 0; i < 255; i++) {
90 sd_read_line(rd, tmp, 128);
91 tmp[3] = 0;
92 tmp[7] = 0;
93 tmp[11] = 0;
94 palette->data[i][0] = atoi(tmp + 0);
95 palette->data[i][1] = atoi(tmp + 4);
96 palette->data[i][2] = atoi(tmp + 8);
97 }
98
99 sd_reader_close(rd);
100 return SD_SUCCESS;
101 }
102
sd_palette_load_range(sd_reader * reader,sd_palette * palette,int index_start,int index_count)103 int sd_palette_load_range(sd_reader *reader, sd_palette *palette, int index_start, int index_count) {
104 char d[3];
105 for(int i = index_start; i < index_start + index_count; i++) {
106 sd_read_buf(reader, d, 3);
107 palette->data[i][0] = ((d[0] << 2) | ((d[0] & 0x30) >> 4));
108 palette->data[i][1] = ((d[1] << 2) | ((d[1] & 0x30) >> 4));
109 palette->data[i][2] = ((d[2] << 2) | ((d[2] & 0x30) >> 4));
110 }
111 return SD_SUCCESS;
112 }
113
sd_palette_mload_range(sd_mreader * reader,sd_palette * palette,int index_start,int index_count)114 int sd_palette_mload_range(sd_mreader *reader, sd_palette *palette, int index_start, int index_count) {
115 char d[3];
116 for(int i = index_start; i < index_start + index_count; i++) {
117 sd_mread_buf(reader, d, 3);
118 palette->data[i][0] = ((d[0] << 2) | ((d[0] & 0x30) >> 4));
119 palette->data[i][1] = ((d[1] << 2) | ((d[1] & 0x30) >> 4));
120 palette->data[i][2] = ((d[2] << 2) | ((d[2] & 0x30) >> 4));
121 }
122 return SD_SUCCESS;
123 }
124
sd_palette_load(sd_reader * reader,sd_palette * palette)125 int sd_palette_load(sd_reader *reader, sd_palette *palette) {
126 sd_palette_load_range(reader, palette, 0, 256);
127 sd_read_buf(reader, (char*)palette->remaps, 19*256);
128 return SD_SUCCESS;
129 }
130
sd_palette_save_range(sd_writer * writer,const sd_palette * palette,int index_start,int index_count)131 void sd_palette_save_range(sd_writer *writer, const sd_palette *palette, int index_start, int index_count) {
132 const unsigned char *d;
133 for(int i = index_start; i < index_start + index_count; i++) {
134 d = palette->data[i];
135 // for some reason, we need to mask off the high bits or the bitshift doesn't work
136 sd_write_ubyte(writer, (d[0] & 0xff) >> 2);
137 sd_write_ubyte(writer, (d[1] & 0xff) >> 2);
138 sd_write_ubyte(writer, (d[2] & 0xff) >> 2);
139 }
140 }
141
sd_palette_msave_range(sd_mwriter * writer,const sd_palette * palette,int index_start,int index_count)142 void sd_palette_msave_range(sd_mwriter *writer, const sd_palette *palette, int index_start, int index_count) {
143 const unsigned char *d;
144 for(int i = index_start; i < index_start + index_count; i++) {
145 d = palette->data[i];
146 // for some reason, we need to mask off the high bits or the bitshift doesn't work
147 sd_mwrite_ubyte(writer, (d[0] & 0xff) >> 2);
148 sd_mwrite_ubyte(writer, (d[1] & 0xff) >> 2);
149 sd_mwrite_ubyte(writer, (d[2] & 0xff) >> 2);
150 }
151 }
152
sd_palette_save(sd_writer * writer,const sd_palette * palette)153 void sd_palette_save(sd_writer *writer, const sd_palette *palette) {
154 sd_palette_save_range(writer, palette, 0, 256);
155 sd_write_buf(writer, (char*)palette->remaps, 19*256);
156 }
157