commit 9acee3ef2c66ac49adb4d0a5b4e1693480a41cd9
parent c4076d28ca0073bcb7507252ce54c6dbb8c162e7
Author: ByteProject <stefan.vogt@byteproject.net>
Date: Sun, 9 Sep 2012 00:45:55 +0200
Retina image output implementation
Diffstat:
3 files changed, 222 insertions(+), 38 deletions(-)
diff --git a/ansilove/ansilove.c b/ansilove/ansilove.c
@@ -43,7 +43,7 @@ void alDrawChar(gdImagePtr im, const unsigned char *font_data, int32_t int_bits,
}
// ANSi
-void alAnsiLoader(char *input, char output[], char font[], char bits[], char icecolors[], char *fext)
+void alAnsiLoader(char *input, char output[], char retinaout[], char font[], char bits[], char icecolors[], char *fext, bool createRetinaRep)
{
const unsigned char *font_data;
@@ -987,6 +987,26 @@ void alAnsiLoader(char *input, char output[], char font[], char bits[], char ice
gdImagePng(im_ANSi, file_Out);
fclose(file_Out);
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_ANSi
+ im_RetinaANSi = gdImageCreate(im_ANSi->sx * 2, im_ANSi->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_ANSi, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_ANSi->sx, im_ANSi->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
+
// free memory
free(ansi_buffer);
@@ -996,7 +1016,7 @@ void alAnsiLoader(char *input, char output[], char font[], char bits[], char ice
}
// PCB
-void alPcBoardLoader(char *input, char output[], char font[], char bits[])
+void alPcBoardLoader(char *input, char output[], char retinaout[], char font[], char bits[], bool createRetinaRep)
{
// some type declarations
int32_t font_size_x;
@@ -1364,12 +1384,32 @@ void alPcBoardLoader(char *input, char output[], char font[], char bits[])
gdImagePng(im_PCB, file_Out);
fclose(file_Out);
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_PCB
+ im_RetinaANSi = gdImageCreate(im_PCB->sx * 2, im_PCB->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_PCB, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_PCB->sx, im_PCB->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
+
// free memory
gdImageDestroy(im_PCB);
}
// BINARY
-void alBinaryLoader(char *input, char output[], char columns[], char font[], char bits[], char icecolors[])
+void alBinaryLoader(char *input, char output[], char retinaout[], char columns[], char font[], char bits[], char icecolors[], bool createRetinaRep)
{
// some type declarations
int32_t font_size_x;
@@ -1618,13 +1658,33 @@ void alBinaryLoader(char *input, char output[], char columns[], char font[], cha
FILE *file_Out = fopen(output, "wb");
gdImagePng(im_Binary, file_Out);
fclose(file_Out);
+
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_Binary
+ im_RetinaANSi = gdImageCreate(im_Binary->sx * 2, im_Binary->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_Binary, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_Binary->sx, im_Binary->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
// free memory
gdImageDestroy(im_Binary);
}
// ADF
-void alArtworxLoader(char *input, char output[], char bits[])
+void alArtworxLoader(char *input, char output[], char retinaout[], char bits[], bool createRetinaRep)
{
const unsigned char *font_data;
unsigned char *font_data_adf;
@@ -1727,12 +1787,32 @@ void alArtworxLoader(char *input, char output[], char bits[])
gdImagePng(im_ADF, file_Out);
fclose(file_Out);
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_ADF
+ im_RetinaANSi = gdImageCreate(im_ADF->sx * 2, im_ADF->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_ADF, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_ADF->sx, im_ADF->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
+
// nuke garbage
gdImageDestroy(im_ADF);
}
// IDF
-void alIcedrawLoader(char *input, char output[], char bits[], bool fileHasSAUCE)
+void alIcedrawLoader(char *input, char output[], char retinaout[], char bits[], bool fileHasSAUCE, bool createRetinaRep)
{
const unsigned char *font_data;
unsigned char *font_data_idf;
@@ -1900,12 +1980,32 @@ void alIcedrawLoader(char *input, char output[], char bits[], bool fileHasSAUCE)
gdImagePng(im_IDF, file_Out);
fclose(file_Out);
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_IDF
+ im_RetinaANSi = gdImageCreate(im_IDF->sx * 2, im_IDF->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_IDF, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_IDF->sx, im_IDF->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
+
// nuke garbage
gdImageDestroy(im_IDF);
}
// TUNDRA
-void alTundraLoader(char *input, char output[], char font[], char bits[])
+void alTundraLoader(char *input, char output[], char retinaout[], char font[], char bits[], bool createRetinaRep)
{
int32_t columns = 80;
int32_t font_size_x;
@@ -2121,12 +2221,32 @@ void alTundraLoader(char *input, char output[], char font[], char bits[])
gdImagePng(im_Tundra, file_Out);
fclose(file_Out);
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_Tundra
+ im_RetinaANSi = gdImageCreate(im_Tundra->sx * 2, im_Tundra->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_Tundra, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_Tundra->sx, im_Tundra->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
+
// free memory
gdImageDestroy(im_Tundra);
}
// XBIN
-void alXbinLoader(char *input, char output[], char bits[])
+void alXbinLoader(char *input, char output[], char retinaout[], char bits[], bool createRetinaRep)
{
const unsigned char *font_data;
unsigned char *font_data_xbin;
@@ -2333,6 +2453,26 @@ void alXbinLoader(char *input, char output[], char bits[])
gdImagePng(im_XBIN, file_Out);
fclose(file_Out);
+ // in case Retina image output is wanted
+ if (createRetinaRep == true)
+ {
+ gdImagePtr im_RetinaANSi;
+
+ // make the Retina image @2x as large as im_XBIN
+ im_RetinaANSi = gdImageCreate(im_XBIN->sx * 2, im_XBIN->sy * 2);
+
+ gdImageCopyResized(im_RetinaANSi, im_XBIN, 0, 0, 0, 0,
+ im_RetinaANSi->sx, im_RetinaANSi->sy,
+ im_XBIN->sx, im_XBIN->sy);
+
+ // create retina output image
+ FILE *file_RetinaOut = fopen(retinaout, "wb");
+ gdImagePng(im_RetinaANSi, file_RetinaOut);
+ fclose(file_RetinaOut);
+
+ gdImageDestroy(im_RetinaANSi);
+ }
+
// nuke garbage
gdImageDestroy(im_XBIN);
}
diff --git a/ansilove/ansilove.h b/ansilove/ansilove.h
@@ -44,13 +44,13 @@ void alDrawChar(gdImagePtr im, const unsigned char *font_data, int32_t int_bits,
int32_t font_size_x, int32_t font_size_y, int32_t position_x, int32_t position_y,
int32_t color_background, int32_t color_foreground, unsigned char character);
-void alAnsiLoader(char *input, char output[], char font[], char bits[], char icecolors[], char *fext);
-void alPcBoardLoader(char *input, char output[], char font[], char bits[]);
-void alBinaryLoader(char *input, char output[], char columns[], char font[], char bits[], char icecolors[]);
-void alArtworxLoader(char *input, char output[], char bits[]);
-void alIcedrawLoader(char *input, char output[], char bits[], bool fileHasSAUCE);
-void alTundraLoader(char *input, char output[], char font[], char bits[]);
-void alXbinLoader(char *input, char output[], char bits[]);
+void alAnsiLoader(char *input, char output[], char retinaout[], char font[], char bits[], char icecolors[], char *fext, bool createRetinaRep);
+void alPcBoardLoader(char *input, char output[], char retinaout[], char font[], char bits[], bool createRetinaRep);
+void alBinaryLoader(char *input, char output[], char retinaout[], char columns[], char font[], char bits[], char icecolors[], bool createRetinaRep);
+void alArtworxLoader(char *input, char output[], char retinaout[], char bits[], bool createRetinaRep);
+void alIcedrawLoader(char *input, char output[], char retinaout[], char bits[], bool fileHasSAUCE, bool createRetinaRep);
+void alTundraLoader(char *input, char output[], char retinaout[], char font[], char bits[], bool createRetinaRep);
+void alXbinLoader(char *input, char output[], char retinaout[], char bits[], bool createRetinaRep);
// helper functions
char *str_replace(const char *string, const char *substr, const char *replacement);
diff --git a/ansilove/main.c b/ansilove/main.c
@@ -52,11 +52,17 @@ void showHelp(void)
void listExamples(void)
{
printf("\nEXAMPLES:\n");
- printf(" ansilove file.ans -i (output identical input with .png suffix, no operands)\n"
- " ansilove file.ans -o foo/out.png (custom path for output, no operands)\n"
+ printf(" ansilove file.ans -i (output path/name identical to input, no operands)\n"
+ " ansilove file.ans -ir (same as -i, adds Retina @2x output file)\n"
+ " ansilove file.ans -o dir/file (custom path/name for output, no operands)\n"
+ " ansilove file.ans -or dir/file (same as -o, adds Retina @2x output file)\n"
" ansilove file.bin -s (just display SAUCE record, don't generate output)\n"
" ansilove file.bin -i terminus 8 1 202 (set font, bits, icecolors, columns)\n"
- " ansilove file.ans -o out.png terminus 8 1 (custom font, bits, icecolors)\n\n");
+ " ansilove file.ans -o dir/file terminus 8 1 (custom font, bits, icecolors)\n"
+ " ansilove file.ans -or dir/file 80x25 8 1 (DOS font, bits, iCE, Retina)\n\n"
+ "HINT:\n"
+ " Don't add .png suffix when specifying a custom path/name for output as it\n"
+ " will be added automatically.\n\n");
}
void versionInfo(void)
@@ -74,17 +80,21 @@ void versionInfo(void)
void synopsis(void)
{
printf("\nSYNOPSIS:\n"
- " ansilove file -i [operands]\n"
- " ansilove file -o file.png [operands]\n"
- " ansilove file -s\n"
+ " ansilove input -i [operands]\n"
+ " ansilove input -ir [operands]\n"
+ " ansilove input -o output [operands]\n"
+ " ansilove input -or output [operands]\n"
+ " ansilove input -s\n"
" ansilove -vhe\n\n"
"OPTIONS:\n"
- " -i output identical to input with .png suffix added\n"
- " -o specify custom file name / path for output\n"
- " -s display SAUCE record without generating output\n"
- " -v version information, equivalent to --version\n"
- " -h show help, equivalent to --help\n"
- " -e print a list of examples\n\n"
+ " -i output identical to input with .png suffix added\n"
+ " -ir same as -i, creates additional Retina @2x output file\n"
+ " -o specify custom file name/path for output\n"
+ " -or same as -o, creates additional Retina @2x output file\n"
+ " -s display SAUCE record without generating output\n"
+ " -v version information, equivalent to --version\n"
+ " -h show help, equivalent to --help\n"
+ " -e print a list of examples\n\n"
"OPERANDS:\n"
" font bits icecolors columns\n\n");
}
@@ -98,6 +108,9 @@ int main(int argc, char *argv[])
bool justDisplaySAUCE = false;
bool fileHasSAUCE = false;
+ // retina output bool type
+ bool createRetinaRep = false;
+
// analyze options and do what has to be done
bool outputIdentical = false;
bool fileIsBinary = false;
@@ -121,14 +134,20 @@ int main(int argc, char *argv[])
listExamples();
return EXIT_SUCCESS;
}
- if ((argv[2] && (strcmp(argv[2], "-s") == 0)) ||
- (argv[2] && (strcmp(argv[2], "-i") == 0)) ||
- (argv[2] && (strcmp(argv[2], "-o") == 0)))
+ if ((argv[2] && (strcmp(argv[2], "-s") == 0)) ||
+ (argv[2] && (strcmp(argv[2], "-i") == 0)) ||
+ (argv[2] && (strcmp(argv[2], "-ir") == 0)) ||
+ (argv[2] && (strcmp(argv[2], "-o") == 0)) ||
+ (argv[2] && (strcmp(argv[2], "-or") == 0)))
{
if (strcmp(argv[2], "-s") == 0) {
justDisplaySAUCE = true;
}
+ if (strcmp(argv[2], "-ir") == 0 || strcmp(argv[2], "-or") == 0) {
+ createRetinaRep = true;
+ }
+
// let's check the file for a valid SAUCE record
sauce *record = sauceReadFileName(argv[1]);
@@ -150,6 +169,7 @@ int main(int argc, char *argv[])
// declaration of types we pass to ansilove.c
char *input = argv[1];
char output[1000] = { 0 };
+ char retinaout[1000] = { 0 };
char columns[1000] = { 0 };
char font[1000] = { 0 };
char bits[1000] = { 0 };
@@ -172,16 +192,31 @@ int main(int argc, char *argv[])
fext = "none";
}
- // in case we got arguments for input and the '-i' flag is set
+ // in case we got arguments for input and the '-i' or '-ir' flag is set
if (strcmp(argv[2], "-i") == 0) {
// append .png suffix to file name
sprintf(output, "%s.png", input);
+ sprintf(retinaout, "placeholder_%s.png", input);
+ outputIdentical = true;
+ }
+
+ if (strcmp(argv[2], "-ir") == 0) {
+ // again, append .png and also add @2x for retina output
+ sprintf(output, "%s.png", input);
+ sprintf(retinaout, "%s@2x.png", input);
outputIdentical = true;
}
if ((strcmp(argv[2], "-o") == 0) && argv[3]) {
// so the user provided an alternate path / file name
- sprintf(output, "%s", argv[3]);
+ sprintf(output, "%s.png", argv[3]);
+ sprintf(retinaout, "placeholder_%s.png", input);
+ }
+
+ if ((strcmp(argv[2], "-or") == 0) && argv[3]) {
+ // alternate path and retina? damn you! even more work.
+ sprintf(output, "%s.png", argv[3]);
+ sprintf(retinaout, "%s@2x.png", argv[3]);
}
if ((strcmp(argv[2], "-o") == 0) && !argv[3]) {
@@ -190,6 +225,12 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
+ if ((strcmp(argv[2], "-or") == 0) && !argv[3]) {
+ // y u no enter output file argument?
+ printf("\nOption -or is invalid without output file argument.\n\n");
+ return EXIT_FAILURE;
+ }
+
// check for operands and apply them based on the file extension
if ((strcmp(fext, ".bin") == 0) && outputIdentical == true)
{
@@ -310,39 +351,42 @@ int main(int argc, char *argv[])
// create the output file by invoking the appropiate function
if (strcmp(fext, ".pcb") == 0) {
// params: input, output, font, bits, icecolors
- alPcBoardLoader(input, output, font, bits);
+ alPcBoardLoader(input, output, retinaout, font, bits, createRetinaRep);
fileIsPCBoard = true;
}
else if (strcmp(fext, ".bin") == 0) {
// params: input, output, columns, font, bits, icecolors
- alBinaryLoader(input, output, columns, font, bits, icecolors);
+ alBinaryLoader(input, output, retinaout, columns, font, bits, icecolors, createRetinaRep);
fileIsBinary = true;
}
else if (strcmp(fext, ".adf") == 0) {
// params: input, output, bits
- alArtworxLoader(input, output, bits);
+ alArtworxLoader(input, output, retinaout, bits, createRetinaRep);
}
else if (strcmp(fext, ".idf") == 0) {
// params: input, output, bits
- alIcedrawLoader(input, output, bits, fileHasSAUCE);
+ alIcedrawLoader(input, output, retinaout, bits, fileHasSAUCE, createRetinaRep);
}
else if (strcmp(fext, ".tnd") == 0) {
- alTundraLoader(input, output, font, bits);
+ alTundraLoader(input, output, retinaout, font, bits, createRetinaRep);
fileIsTundra = true;
}
else if (strcmp(fext, ".xb") == 0) {
// params: input, output, bits
- alXbinLoader(input, output, bits);
+ alXbinLoader(input, output, retinaout, bits, createRetinaRep);
}
else {
// params: input, output, font, bits, icecolors, fext
- alAnsiLoader(input, output, font, bits, icecolors, fext);
+ alAnsiLoader(input, output, retinaout, font, bits, icecolors, fext, createRetinaRep);
fileIsANSi = true;
}
// gather information and report to the command line
printf("\nInput File: %s\n", input);
printf("Output File: %s\n", output);
+ if (createRetinaRep == true) {
+ printf("Retina Output File: %s\n", retinaout);
+ }
if (fileIsANSi == true || fileIsBinary == true ||
fileIsPCBoard == true || fileIsTundra == true) {
printf("Font: %s\n", font);