diff --git a/LICENSE b/LICENSE index a8d669a..8304b66 100644 --- a/LICENSE +++ b/LICENSE @@ -18,12 +18,6 @@ released under the following license: rgbfix was rewritten from scratch by Anthony J. Bentley, and is released under the ISC license; see the source file for the text of the license. -rgbgfx was written by stag019, and is released under the ISC license. - -The UTF-8 decoder in src/asm/charmap.c was written by Björn Höhrmann and is -released under the MIT license. The remainder of charmap.c was written by -stag019, and is released under the ISC license. - extern/err.c is derived from the Musl C library, http://www.musl-libc.org, and is released under the MIT license. diff --git a/Makefile b/Makefile index e01e028..ac92655 100644 --- a/Makefile +++ b/Makefile @@ -43,9 +43,10 @@ rgbfix_obj = \ src/extern/err.o rgbgfx_obj = \ - src/gfx/gb.o \ src/gfx/main.o \ - src/gfx/png.o + src/gfx/png.o \ + src/gfx/gb.o \ + src/extern/err.o all: rgbasm rgblink rgbfix rgbgfx @@ -54,7 +55,7 @@ clean: $Qrm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html $Qrm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html $Qrm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html - $Qrm -rf rgbgfx rgbgfx.exe ${rgbgfx_obj} rgbgfx.html + $Qrm -rf rgbgfx ${rgbgfx_obj} $Qrm -rf src/asm/asmy.c src/asm/asmy.h install: all @@ -80,7 +81,7 @@ rgbfix: ${rgbfix_obj} $Q${CC} ${REALCFLAGS} -o $@ ${rgbfix_obj} rgbgfx: ${rgbgfx_obj} - $Q${CC} ${REALCFLAGS} -o $@ ${rgbfix_obj} + $Q${CC} ${REALCFLAGS} -o $@ ${rgbgfx_obj} `pkg-config --libs libpng` .y.c: $Q${YACC} -d ${YFLAGS} -o $@ $< @@ -88,6 +89,9 @@ rgbgfx: ${rgbgfx_obj} .c.o: $Q${CC} ${REALCFLAGS} -c -o $@ $< +src/gfx/%.o: src/gfx/%.c + $Q${CC} ${REALCFLAGS} `pkg-config --cflags libpng` -c -o $@ $< + src/asm/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h src/asm/asmy.h: src/asm/asmy.c @@ -116,5 +120,3 @@ wwwman: rgbfix.html $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \ rgblink.html - $Qmandoc ${MANDOC} src/gfx/rgbgfx.1 | sed s/OpenBSD/General/ > \ - rgbgfx.html diff --git a/README b/README index 4541231..6d609ee 100644 --- a/README +++ b/README @@ -8,7 +8,7 @@ for the Game Boy and Game Boy Color. It consists of: - rgbasm (assembler) - rgblink (linker) - rgbfix (checksum/header fixer) - - rgbgfx (PNG‐to‐Game Boy graphics converter) + - rgbgfx (graphics converter) rgbds-linux is a fork of the original RGBDS which aims to make the programs more like other UNIX tools. diff --git a/include/gfx/main.h b/include/gfx/main.h index ce2d3dd..05f0baa 100644 --- a/include/gfx/main.h +++ b/include/gfx/main.h @@ -17,8 +17,14 @@ #ifndef RGBDS_GFX_MAIN_H #define RGBDS_GFX_MAIN_H +#include +#include +#include +#include +#include #include #include + #include "extern/err.h" #define strequ(str1, str2) (strcmp(str1, str2) == 0) diff --git a/include/link/main.h b/include/link/main.h index 218ca6d..3915f49 100644 --- a/include/link/main.h +++ b/include/link/main.h @@ -4,6 +4,6 @@ #include "types.h" extern SLONG fillchar; -extern char *smartlinkstartsymbol; +extern char smartlinkstartsymbol[256]; #endif diff --git a/src/asm/asmy.y b/src/asm/asmy.y index 46d4554..ee18125 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -20,49 +20,6 @@ char *tzNewMacro; ULONG ulNewMacroSize; -void -bankrangecheck(char *name, ULONG secttype, SLONG org, SLONG bank) -{ - SLONG minbank, maxbank; - char *stype; - switch (secttype) { - case SECT_ROMX: - stype = "ROMX"; - minbank = 1; - maxbank = 0x1ff; - break; - case SECT_SRAM: - stype = "SRAM"; - minbank = 0; - maxbank = 0x1ff; - break; - case SECT_WRAMX: - stype = "WRAMX"; - minbank = 1; - maxbank = 7; - break; - case SECT_VRAM: - stype = "VRAM"; - minbank = 0; - maxbank = 1; - break; - default: - yyerror("BANK only allowed for " - "ROMX, WRAMX, SRAM, or VRAM sections"); - } - - if (bank < minbank || bank > maxbank) { - yyerror("%s bank value $%x out of range ($%x to $%x)", - stype, bank, minbank, maxbank); - } - - if (secttype == SECT_WRAMX) { - bank -= minbank; - } - - out_NewAbsSection(name, secttype, org, bank); -} - size_t symvaluetostring(char *dest, size_t maxLength, char *sym) { size_t length; @@ -1097,14 +1054,76 @@ section: } | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' { - bankrangecheck($2, $4, -1, $8); + if( $4==SECT_ROMX ) { + if( $8>=1 && $8<=0x1ff ) + out_NewAbsSection($2,$4,-1,$8); + else + yyerror("ROM bank value $%x out of range (1 to $1ff)", $8); + } else if ($4 == SECT_SRAM) { + if ($8 >= 0 && $8 <= 3) { + out_NewAbsSection($2, $4, -1, $8); + } else { + yyerror("SRAM bank value $%x out of range (0 to 3)", $8); + } + } else if ($4 == SECT_WRAMX) { + if ($8 >= 1 && $8 <= 7) { + out_NewAbsSection($2, $4, -1, $8 - 1); + } else { + yyerror("WRAMX bank value $%x out of range (1 to 7)", $8); + } + } else if ($4 == SECT_VRAM) { + if ($8 >= 0 && $8 <= 1) { + out_NewAbsSection($2, $4, -1, $8); + } else { + yyerror("VRAM bank value $%x out of range (0 to 1)", $8); + } + } else { + yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections"); + } } | T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']' { - if ($6 < 0 || $6 > 0x10000) { - yyerror("Address $%x not 16-bit", $6); + if( $4==SECT_ROMX ) { + if( $6>=0 && $6<0x10000 ) { + if( $11>=1 && $11<=0x1ff ) + out_NewAbsSection($2,$4,$6,$11); + else + yyerror("ROM bank value $%x out of range (1 to $1ff)", $11); + } else + yyerror("Address $%x not 16-bit", $6); + } else if ($4 == SECT_SRAM) { + if ($6 >= 0 && $6 < 0x10000) { + if ($11 >= 0 && $11 <= 3) { + out_NewAbsSection($2, $4, $6, $11); + } else { + yyerror("SRAM bank value $%x out of range (0 to 3)", $11); + } + } else { + yyerror("Address $%x not 16-bit", $6); + } + } else if ($4 == SECT_WRAMX) { + if ($6 >= 0 && $6 < 0x10000) { + if ($11 >= 1 && $11 <= 7) { + out_NewAbsSection($2, $4, $6, $11 - 1); + } else { + yyerror("WRAMX bank value $%x out of range (1 to 7)", $11); + } + } else { + yyerror("Address $%x not 16-bit", $6); + } + } else if ($4 == SECT_VRAM) { + if ($6 >= 0 && $6 < 0x10000) { + if ($11 >= 0 && $11 <= 1) { + out_NewAbsSection($2,$4,$6,$11); + } else { + yyerror("VRAM bank value $%x out of range (0 to 1)", $11); + } + } else { + yyerror("Address $%x not 16-bit", $6); + } + } else { + yyerror("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections"); } - bankrangecheck($2, $4, $6, $11); } ; diff --git a/src/asm/charmap.c b/src/asm/charmap.c index 370f198..4f2aecf 100644 --- a/src/asm/charmap.c +++ b/src/asm/charmap.c @@ -1,58 +1,4 @@ /* - * UTF-8 decoder copyright © 2008–2009 Björn Höhrmann - * http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -static const uint8_t utf8d[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df - 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef - 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff - 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 - 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 - 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 - 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 -}; - -uint32_t -decode(uint32_t* state, uint32_t* codep, uint32_t byte) { - uint32_t type = utf8d[byte]; - - *codep = (*state != 0) ? - (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); - - *state = utf8d[256 + *state*16 + type]; - return *state; -} - -/* * Copyright © 2013 stag019 * * Permission to use, copy, modify, and distribute this software for any @@ -82,94 +28,122 @@ struct Charmap globalCharmap = {0}; extern struct Section *pCurrentSection; int -readUTF8Char(char *dest, char *src) +readUTF8Char(char *destination, char *source) { - uint32_t state; - uint32_t codep; - int i; - - for (i = 0, state = 0;; i++) { - if (decode(&state, &codep, (uint8_t)src[i]) == 1) { - fatalerror("invalid UTF-8 character"); - } + int size; + UBYTE first; + first = source[0]; - dest[i] = src[i]; - - i++; - if (state == 0) { - dest[i] = '\0'; - return i; - } - dest[i] = src[i]; + if(first >= 0xFC) + { + size = 6; + } + else if(first >= 0xF8) + { + size = 5; } + else if(first >= 0xF0) + { + size = 4; + } + else if(first >= 0xE0) + { + size = 3; + } + else if(first >= 0xC0) + { + size = 2; + } + else if(first != '\0') + { + size = 1; + } + else + { + size = 0; + } + strncpy(destination, source, size); + destination[size] = 0; + return size; } int charmap_Add(char *input, UBYTE output) { int i, input_length; - char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1], temp1o = 0, - temp2o = 0; + char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1], temp1o = 0, temp2o = 0; struct Charmap *charmap; - if (pCurrentSection) { - if (pCurrentSection->charmap) { - charmap = pCurrentSection->charmap; - } else { - if ((charmap = calloc(1, sizeof(struct Charmap))) == - NULL) { + if(pCurrentSection) + { + if(pCurrentSection -> charmap) + { + charmap = pCurrentSection -> charmap; + } + else + { + if((charmap = (struct Charmap *) calloc(1, sizeof(struct Charmap))) == NULL) + { fatalerror("Not enough memory for charmap"); } - pCurrentSection->charmap = charmap; + pCurrentSection -> charmap = charmap; } - } else { + } + else + { charmap = &globalCharmap; } - if (nPass == 2) { - return charmap->count; + if(nPass == 2) + { + return charmap -> count; } - if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH) { + if(charmap -> count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH) + { return -1; } input_length = strlen(input); - if (input_length > 1) { + if(input_length > 1) + { i = 0; - while (i < charmap->count + 1) { - if (input_length > strlen(charmap->input[i])) { - memcpy(temp1i, charmap->input[i], - CHARMAPLENGTH + 1); - memcpy(charmap->input[i], input, input_length); - temp1o = charmap->output[i]; - charmap->output[i] = output; + while(i < charmap -> count + 1) + { + if(input_length > strlen(charmap -> input[i])) + { + memcpy(temp1i, charmap -> input[i], CHARMAPLENGTH + 1); + memcpy(charmap -> input[i], input, input_length); + temp1o = charmap -> output[i]; + charmap -> output[i] = output; i++; break; } i++; } - while (i < charmap->count + 1) { - memcpy(temp2i, charmap->input[i], CHARMAPLENGTH + 1); - memcpy(charmap->input[i], temp1i, CHARMAPLENGTH + 1); + while(i < charmap -> count + 1) + { + memcpy(temp2i, charmap -> input[i], CHARMAPLENGTH + 1); + memcpy(charmap -> input[i], temp1i, CHARMAPLENGTH + 1); memcpy(temp1i, temp2i, CHARMAPLENGTH + 1); - temp2o = charmap->output[i]; - charmap->output[i] = temp1o; + temp2o = charmap -> output[i]; + charmap -> output[i] = temp1o; temp1o = temp2o; i++; } - memcpy(charmap->input[charmap->count + 1], temp1i, - CHARMAPLENGTH + 1); - charmap->output[charmap->count + 1] = temp1o; - } else { - memcpy(charmap->input[charmap->count], input, input_length); - charmap->output[charmap->count] = output; - } - return ++charmap->count; + memcpy(charmap -> input[charmap -> count + 1], temp1i, CHARMAPLENGTH + 1); + charmap -> output[charmap -> count + 1] = temp1o; + } + else + { + memcpy(charmap -> input[charmap -> count], input, input_length); + charmap -> output[charmap -> count] = output; + } + return ++charmap -> count; } -int +int charmap_Convert(char **input) { struct Charmap *charmap; @@ -178,35 +152,47 @@ charmap_Convert(char **input) char *buffer; int i, j, length; - if (pCurrentSection && pCurrentSection->charmap) { - charmap = pCurrentSection->charmap; - } else { + if(pCurrentSection && pCurrentSection -> charmap) + { + charmap = pCurrentSection -> charmap; + } + else + { charmap = &globalCharmap; } - if ((buffer = malloc(strlen(*input))) == NULL) { + if((buffer = (char *) malloc(strlen(*input))) == NULL) + { fatalerror("Not enough memory for buffer"); } length = 0; - while (**input) { + while(**input) + { j = 0; - for (i = 0; i < charmap->count; i++) { - j = strlen(charmap->input[i]); - if (memcmp(*input, charmap->input[i], j) == 0) { - outchar[0] = charmap->output[i]; + for(i = 0; i < charmap -> count; i++) + { + j = strlen(charmap -> input[i]); + if(memcmp(*input, charmap -> input[i], j) == 0) + { + outchar[0] = charmap -> output[i]; outchar[1] = 0; break; } j = 0; } - if (!j) { + if(!j) + { j = readUTF8Char(outchar, *input); } - if (!outchar[0]) { + if(!outchar[0]) + { buffer[length++] = 0; - } else { - for (i = 0; outchar[i]; i++) { + } + else + { + for(i = 0; outchar[i]; i++) + { buffer[length++] = outchar[i]; } } @@ -215,3 +201,4 @@ charmap_Convert(char **input) *input = buffer; return length; } + diff --git a/src/gfx/gb.c b/src/gfx/gb.c index a352ff2..28f2b04 100644 --- a/src/gfx/gb.c +++ b/src/gfx/gb.c @@ -14,19 +14,15 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "gfx/main.h" -void -transpose_tiles(struct GBImage *gb, int width) -{ +void transpose_tiles(struct GBImage *gb, int width) { uint8_t *newdata; int i; int newbyte; newdata = calloc(gb->size, 1); - for (i = 0; i < gb->size; i++) { + for(i = 0; i < gb->size; i++) { newbyte = i / (8 * gb->depth) * width * 8 * gb->depth; newbyte = newbyte % gb->size + 8 * gb->depth * (newbyte / gb->size) + i % (8 * gb->depth); newdata[newbyte] = gb->data[i]; @@ -37,87 +33,80 @@ transpose_tiles(struct GBImage *gb, int width) gb->data = newdata; } -void -png_to_gb(struct PNGImage png, struct GBImage *gb) -{ +void png_to_gb(struct PNGImage png, struct GBImage *gb) { int x, y, byte; png_byte *row, index; - for (y = 0; y < png.height; y++) { + for(y = 0; y < png.height; y++) { row = png.data[y]; - for (x = 0; x < png.width; x++) { + for(x = 0; x < png.width; x++) { index = row[x / (4 * (3 - gb->depth))] >> (8 - gb->depth - (x % (4 * (3 - gb->depth)) * gb->depth)) & 3; - if (png.type == PNG_COLOR_TYPE_GRAY) { + if(png.type == PNG_COLOR_TYPE_GRAY) { index = (gb->depth == 2 ? 3 : 1) - index; } - if (!gb->horizontal) { + if(!gb->horizontal) { byte = y * gb->depth + x / 8 * png.height / 8 * 8 * gb->depth; } else { byte = y * gb->depth + x / 8 * png.height / 8 * 8 * gb->depth; } gb->data[byte] |= (index & 1) << (7 - x % 8); - if (gb->depth > 1) { + if(gb->depth > 1) { gb->data[byte + 1] |= (index >> 1) << (7 - x % 8); } } } - if (!gb->horizontal) { + if(!gb->horizontal) { transpose_tiles(gb, png.width / 8); } } -void -output_file(struct Options opts, struct GBImage gb) -{ +void output_file(struct Options opts, struct GBImage gb) { FILE *f; f = fopen(opts.outfile, "wb"); - if (!f) { - err(1, "Opening output file '%s' failed", opts.outfile); + if(!f) { + err(EXIT_FAILURE, "Opening output file '%s' failed", opts.outfile); } fwrite(gb.data, 1, gb.size - gb.trim * 8 * gb.depth, f); fclose(f); } -void -output_tilemap_file(struct Options opts) -{ +void output_tilemap_file(struct Options opts) { FILE *f; f = fopen(opts.mapfile, "wb"); - if (!f) { - err(1, "Opening tilemap file '%s' failed", opts.mapfile); + if(!f) { + err(EXIT_FAILURE, "Opening tilemap file '%s' failed", opts.mapfile); } fclose(f); - if (opts.mapout) { + if(opts.mapout) { free(opts.mapfile); } } -void -output_palette_file(struct Options opts, struct PNGImage png) -{ +void output_palette_file(struct Options opts, struct PNGImage png) { FILE *f; int i, colors, color; png_color *palette; - if (png_get_PLTE(png.png, png.info, &palette, &colors)) { + if(png_get_PLTE(png.png, png.info, &palette, &colors)) { f = fopen(opts.palfile, "wb"); - if (!f) { - err(1, "Opening palette file '%s' failed", opts.palfile); + if(!f) { + err(EXIT_FAILURE, "Opening palette file '%s' failed", opts.palfile); } - for (i = 0; i < colors; i++) { + for(i = 0; i < colors; i++) { color = palette[i].blue >> 3 << 10 | palette[i].green >> 3 << 5 | palette[i].red >> 3; fwrite(&color, 2, 1, f); } fclose(f); } - if (opts.palout) { + if(opts.palout) { free(opts.palfile); } } + diff --git a/src/gfx/main.c b/src/gfx/main.c index 075077d..760dac8 100644 --- a/src/gfx/main.c +++ b/src/gfx/main.c @@ -14,28 +14,18 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include - #include "gfx/main.h" -static void -usage(void) -{ +char *progname; + +static void usage(void) { printf( "Usage: rgbgfx [-v] [-F] [-f] [-b] [-h] [-x #] [-t mapfile] [-T] [-p palfile]\n" " [-P] [-o outfile] infile\n"); exit(1); } -int -main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { int ch, size; struct Options opts = {0}; struct PNGImage png = {0}; @@ -43,15 +33,17 @@ main(int argc, char *argv[]) char *ext; const char *errmsg = "Warning: The PNG's %s setting is not the same as the setting defined on the command line."; - if (argc == 1) { + if(argc == 1) { usage(); } + progname = argv[0]; + opts.mapfile = ""; opts.palfile = ""; opts.outfile = ""; - while ((ch = getopt(argc, argv, "DvFfbhx:Tt:Pp:o:")) != -1) { + while((ch = getopt(argc, argv, "DvFfbhx:Tt:Pp:o:")) != -1) { switch(ch) { case 'D': opts.debug = true; @@ -95,7 +87,7 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc == 0) { + if(argc == 0) { usage(); } @@ -108,83 +100,83 @@ main(int argc, char *argv[]) get_text(&png); - if (png.horizontal != opts.horizontal) { - if (opts.verbose) { + if(png.horizontal != opts.horizontal) { + if(opts.verbose) { warnx(errmsg, "horizontal"); } - if (opts.hardfix) { + if(opts.hardfix) { png.horizontal = opts.horizontal; } } - if (png.horizontal) { + if(png.horizontal) { opts.horizontal = png.horizontal; } - if (png.trim != opts.trim) { - if (opts.verbose) { + if(png.trim != opts.trim) { + if(opts.verbose) { warnx(errmsg, "trim"); } - if (opts.hardfix) { + if(opts.hardfix) { png.trim = opts.trim; } } - if (png.trim) { + if(png.trim) { opts.trim = png.trim; } - if (opts.trim > png.width / 8 - 1) { + if(opts.trim > png.width / 8 - 1) { errx(EXIT_FAILURE, "Trim (%i) for input png file '%s' too large (max: %i)", opts.trim, opts.infile, png.width / 8 - 1); } - if (!strequ(png.mapfile, opts.mapfile)) { - if (opts.verbose) { + if(!strequ(png.mapfile, opts.mapfile)) { + if(opts.verbose) { warnx(errmsg, "tilemap file"); } - if (opts.hardfix) { + if(opts.hardfix) { png.mapfile = opts.mapfile; } } - if (!*opts.mapfile) { + if(!*opts.mapfile) { opts.mapfile = png.mapfile; } - if (png.mapout != opts.mapout) { - if (opts.verbose) { + if(png.mapout != opts.mapout) { + if(opts.verbose) { warnx(errmsg, "tilemap file"); } - if (opts.hardfix) { + if(opts.hardfix) { png.mapout = opts.mapout; } } - if (png.mapout) { + if(png.mapout) { opts.mapout = png.mapout; } - if (!strequ(png.palfile, opts.palfile)) { - if (opts.verbose) { + if(!strequ(png.palfile, opts.palfile)) { + if(opts.verbose) { warnx(errmsg, "pallette file"); } - if (opts.hardfix) { + if(opts.hardfix) { png.palfile = opts.palfile; } } - if (!*opts.palfile) { + if(!*opts.palfile) { opts.palfile = png.palfile; } - if (png.palout != opts.palout) { - if (opts.verbose) { + if(png.palout != opts.palout) { + if(opts.verbose) { warnx(errmsg, "pallette file"); } - if (opts.hardfix) { + if(opts.hardfix) { png.palout = opts.palout; } } - if (png.palout) { + if(png.palout) { opts.palout = png.palout; } - if (!*opts.mapfile && opts.mapout) { - if ((ext = strrchr(opts.infile, '.')) != NULL) { + if(!*opts.mapfile && opts.mapout) { + if((ext = strrchr(opts.infile, '.')) != NULL) { size = ext - opts.infile + 9; opts.mapfile = malloc(size); strncpy(opts.mapfile, opts.infile, size); @@ -197,8 +189,8 @@ main(int argc, char *argv[]) } } - if (!*opts.palfile && opts.palout) { - if ((ext = strrchr(opts.infile, '.')) != NULL) { + if(!*opts.palfile && opts.palout) { + if((ext = strrchr(opts.infile, '.')) != NULL) { size = ext - opts.infile + 5; opts.palfile = malloc(size); strncpy(opts.palfile, opts.infile, size); @@ -217,20 +209,20 @@ main(int argc, char *argv[]) gb.trim = opts.trim; gb.horizontal = opts.horizontal; - if (*opts.outfile) { + if(*opts.outfile) { png_to_gb(png, &gb); output_file(opts, gb); } - if (*opts.mapfile) { + if(*opts.mapfile) { output_tilemap_file(opts); } - if (*opts.palfile) { + if(*opts.palfile) { output_palette_file(opts, png); } - if (opts.fix || opts.debug) { + if(opts.fix || opts.debug) { set_text(&png); output_png_file(opts, &png); } @@ -240,3 +232,4 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } + diff --git a/src/gfx/png.c b/src/gfx/png.c index b51ecca..e5af7e7 100644 --- a/src/gfx/png.c +++ b/src/gfx/png.c @@ -14,15 +14,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include #include "gfx/main.h" -void -input_png_file(struct Options opts, struct PNGImage *img) -{ +void input_png_file(struct Options opts, struct PNGImage *img) { FILE *f; int i, y, num_trans, depth, colors; bool has_palette; @@ -35,23 +29,23 @@ input_png_file(struct Options opts, struct PNGImage *img) colors = depth * depth; f = fopen(opts.infile, "rb"); - if (!f) { - err(1, "Opening input png file '%s' failed", opts.infile); + if(!f) { + err(EXIT_FAILURE, "Opening input png file '%s' failed", opts.infile); } img->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!img->png) { - errx(1, "Creating png structure failed"); + if(!img->png) { + errx(EXIT_FAILURE, "Creating png structure failed"); } img->info = png_create_info_struct(img->png); - if (!img->info) { - errx(1, "Creating png info structure failed"); + if(!img->info) { + errx(EXIT_FAILURE, "Creating png info structure failed"); } /* Better error handling here? */ - if (setjmp(png_jmpbuf(img->png))) { - exit(1); + if(setjmp(png_jmpbuf(img->png))) { + exit(EXIT_FAILURE); } png_init_io(img->png, f); @@ -63,38 +57,38 @@ input_png_file(struct Options opts, struct PNGImage *img) img->depth = png_get_bit_depth(img->png, img->info); img->type = png_get_color_type(img->png, img->info); - if (img->type & PNG_COLOR_MASK_ALPHA) { + if(img->type & PNG_COLOR_MASK_ALPHA) { png_set_strip_alpha(img->png); } - if (img->depth != depth) { - if (opts.verbose) { + if(img->depth != depth) { + if(opts.verbose) { warnx("Image bit depth is not %i.", depth); } - if (img->type == PNG_COLOR_TYPE_GRAY) { - if (img->depth < 8) { - png_set_gray_1_2_4_to_8(img->png); + if(img->type == PNG_COLOR_TYPE_GRAY) { + if(img->depth < 8) { + png_set_expand_gray_1_2_4_to_8(img->png); } png_set_gray_to_rgb(img->png); } else { has_palette = png_get_PLTE(img->png, img->info, &palette, &colors); } - if (png_get_tRNS(img->png, img->info, &trans_alpha, &num_trans, &trans_values)) { - if (img->type == PNG_COLOR_TYPE_PALETTE) { + if(png_get_tRNS(img->png, img->info, &trans_alpha, &num_trans, &trans_values)) { + if(img->type == PNG_COLOR_TYPE_PALETTE) { full_alpha = malloc(sizeof(bool) * num_trans); - for (i = 0; i < num_trans; i++) { - if (trans_alpha[i] > 0) { + for(i = 0; i < num_trans; i++) { + if(trans_alpha[i] > 0) { full_alpha[i] = false; } else { full_alpha[i] = true; } } - for (i = 0; i < num_trans; i++) { - if (full_alpha[i]) { + for(i = 0; i < num_trans; i++) { + if(full_alpha[i]) { palette[i].red = 0xFF; palette[i].green = 0x00; palette[i].blue = 0xFF; @@ -110,13 +104,13 @@ input_png_file(struct Options opts, struct PNGImage *img) png_free_data(img->png, img->info, PNG_FREE_TRNS, -1); } - if (has_palette) { + if(has_palette) { /* Make sure palette only has the amount of colors you want. */ } else { /* Eventually when this copies colors from the image itself, make sure order is lightest to darkest. */ palette = malloc(sizeof(png_color) * colors); - if (strequ(opts.infile, "rgb.png")) { + if(strequ(opts.infile, "rgb.png")) { palette[0].red = 0xFF; palette[0].green = 0xEF; palette[0].blue = 0xFF; @@ -152,9 +146,9 @@ input_png_file(struct Options opts, struct PNGImage *img) } /* Also unfortunately, this sets it at 8 bit, and I cant find any option to reduce to 2 or 1 bit. */ - png_set_dither(img->png, palette, colors, colors, NULL, 1); + png_set_quantize(img->png, palette, colors, colors, NULL, 1); - if (!has_palette) { + if(!has_palette) { png_set_PLTE(img->png, img->info, palette, colors); free(palette); } @@ -165,7 +159,7 @@ input_png_file(struct Options opts, struct PNGImage *img) png_read_update_info(img->png, img->info); img->data = malloc(sizeof(png_byte *) * img->height); - for (y = 0; y < img->height; y++) { + for(y = 0; y < img->height; y++) { img->data[y] = malloc(png_get_rowbytes(img->png, img->info)); } @@ -175,87 +169,83 @@ input_png_file(struct Options opts, struct PNGImage *img) fclose(f); } -void -get_text(struct PNGImage *png) -{ +void get_text(struct PNGImage *png) { png_text *text; int i, numtxts, numremoved; png_get_text(png->png, png->info, &text, &numtxts); - for (i = 0; i < numtxts; i++) { - if (strequ(text[i].key, "h") && !*text[i].text) { + for(i = 0; i < numtxts; i++) { + if(strequ(text[i].key, "h") && !*text[i].text) { png->horizontal = true; png_free_data(png->png, png->info, PNG_FREE_TEXT, i); - } else if (strequ(text[i].key, "x")) { + } else if(strequ(text[i].key, "x")) { png->trim = strtoul(text[i].text, NULL, 0); png_free_data(png->png, png->info, PNG_FREE_TEXT, i); - } else if (strequ(text[i].key, "t")) { + } else if(strequ(text[i].key, "t")) { png->mapfile = text[i].text; png_free_data(png->png, png->info, PNG_FREE_TEXT, i); - } else if (strequ(text[i].key, "T") && !*text[i].text) { + } else if(strequ(text[i].key, "T") && !*text[i].text) { png->mapout = true; png_free_data(png->png, png->info, PNG_FREE_TEXT, i); - } else if (strequ(text[i].key, "p")) { + } else if(strequ(text[i].key, "p")) { png->palfile = text[i].text; png_free_data(png->png, png->info, PNG_FREE_TEXT, i); - } else if (strequ(text[i].key, "P") && !*text[i].text) { + } else if(strequ(text[i].key, "P") && !*text[i].text) { png->palout = true; png_free_data(png->png, png->info, PNG_FREE_TEXT, i); } } /* TODO: Remove this and simply change the warning function not to warn instead. */ - for (i = 0, numremoved = 0; i < numtxts; i++) { - if (text[i].key == NULL) { + for(i = 0, numremoved = 0; i < numtxts; i++) { + if(text[i].key == NULL) { numremoved++; } text[i].key = text[i + numremoved].key; text[i].text = text[i + numremoved].text; text[i].compression = text[i + numremoved].compression; } - png->info->num_text -= numremoved; + png_set_text(png->png, png->info, text, numtxts - numremoved); } -void -set_text(struct PNGImage *png) -{ +void set_text(struct PNGImage *png) { png_text *text; char buffer[3]; text = malloc(sizeof(png_text)); - if (png->horizontal) { + if(png->horizontal) { text[0].key = "h"; text[0].text = ""; text[0].compression = PNG_TEXT_COMPRESSION_NONE; png_set_text(png->png, png->info, text, 1); } - if (png->trim) { + if(png->trim) { text[0].key = "x"; snprintf(buffer, 3, "%d", png->trim); text[0].text = buffer; text[0].compression = PNG_TEXT_COMPRESSION_NONE; png_set_text(png->png, png->info, text, 1); } - if (*png->mapfile) { + if(*png->mapfile) { text[0].key = "t"; text[0].text = ""; text[0].compression = PNG_TEXT_COMPRESSION_NONE; png_set_text(png->png, png->info, text, 1); } - if (png->mapout) { + if(png->mapout) { text[0].key = "T"; text[0].text = ""; text[0].compression = PNG_TEXT_COMPRESSION_NONE; png_set_text(png->png, png->info, text, 1); } - if (*png->palfile) { + if(*png->palfile) { text[0].key = "p"; text[0].text = ""; text[0].compression = PNG_TEXT_COMPRESSION_NONE; png_set_text(png->png, png->info, text, 1); } - if (png->palout) { + if(png->palout) { text[0].key = "P"; text[0].text = ""; text[0].compression = PNG_TEXT_COMPRESSION_NONE; @@ -265,15 +255,13 @@ set_text(struct PNGImage *png) free(text); } -void -output_png_file(struct Options opts, struct PNGImage *png) -{ +void output_png_file(struct Options opts, struct PNGImage *png) { FILE *f; char *outfile; png_struct *img; /* Variable outfile is for debugging purposes. Eventually, opts.infile will be used directly. */ - if (opts.debug) { + if(opts.debug) { outfile = malloc(strlen(opts.infile) + 5); strcpy(outfile, opts.infile); strcat(outfile, ".out"); @@ -282,18 +270,18 @@ output_png_file(struct Options opts, struct PNGImage *png) } f = fopen(outfile, "wb"); - if (!f) { - err(1, "Opening output png file '%s' failed", outfile); + if(!f) { + err(EXIT_FAILURE, "Opening output png file '%s' failed", outfile); } img = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!img) { - errx(1, "Creating png structure failed"); + if(!img) { + errx(EXIT_FAILURE, "Creating png structure failed"); } /* Better error handling here? */ - if (setjmp(png_jmpbuf(img))) { - exit(1); + if(setjmp(png_jmpbuf(img))) { + exit(EXIT_FAILURE); } png_init_io(img, f); @@ -305,18 +293,17 @@ output_png_file(struct Options opts, struct PNGImage *png) fclose(f); - if (opts.debug) { + if(opts.debug) { free(outfile); } } -void -free_png_data(struct PNGImage *png) -{ +void free_png_data(struct PNGImage *png) { int y; - for (y = 0; y < png->height; y++) { + for(y = 0; y < png->height; y++) { free(png->data[y]); } free(png->data); } + diff --git a/src/link/main.c b/src/link/main.c index 8eda44a..954d023 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -22,7 +22,7 @@ enum eBlockType { SLONG options = 0; SLONG fillchar = 0; -char *smartlinkstartsymbol; +char smartlinkstartsymbol[256]; char *progname; @@ -79,7 +79,7 @@ main(int argc, char *argv[]) break; case 's': options |= OPT_SMART_C_LINK; - smartlinkstartsymbol = optarg; + strcpy(smartlinkstartsymbol, optarg); break; case 't': options |= OPT_SMALL;