From 817d129be8a076744a4d2d8d04e0d682f5d99fad Mon Sep 17 00:00:00 2001 From: karri Date: Thu, 29 Dec 2022 19:18:00 +0200 Subject: [PATCH 01/11] Add support for 4 pixels per plane --- src/sp65/pcx.c | 171 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 141 insertions(+), 30 deletions(-) diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index d721671b3..489c65c5d 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -153,11 +153,12 @@ static PCXHeader* ReadPCXHeader (FILE* F, const char* Name) P->Compressed, Name); } /* We support: - ** - one plane with either 1 or 8 bits per pixel - ** - three planes with 8 bits per pixel - ** - four planes with 8 bits per pixel (does this exist?) - */ + * - one plane with either 1, 4 or 8 bits per pixel + * - three planes with 8 bits per pixel + * - four planes with 8 bits per pixel (does this exist?) + */ if (!((P->BPP == 1 && P->Planes == 1) || + (P->BPP == 4 && P->Planes == 1) || (P->BPP == 8 && (P->Planes == 1 || P->Planes == 3 || P->Planes == 4)))) { /* We could support others, but currently we don't */ Error ("Unsupported PCX format: %u planes, %u bpp in PCX file '%s'", @@ -204,11 +205,14 @@ static void DumpPCXHeader (const PCXHeader* P, const char* Name) static void ReadPlane (FILE* F, PCXHeader* P, unsigned char* L) /* Read one (possibly compressed) plane from the file */ { - if (P->Compressed) { + unsigned i; + if (P->Compressed) { /* Uncompress RLE data */ - unsigned Remaining = P->Width; - while (Remaining) { + signed Remaining = P->BytesPerPlane; + signed WidthCounter = P->Width; + + while (Remaining > 0) { unsigned char C; @@ -224,21 +228,111 @@ static void ReadPlane (FILE* F, PCXHeader* P, unsigned char* L) } /* Write the data to the buffer */ - if (C > Remaining) { - C = Remaining; - } - memset (L, B, C); - - /* Bump counters */ - L += C; - Remaining -= C; - + switch (P->BPP) { + default: + for (i = 0; i < C; i++) { + if (WidthCounter > 0) { + *L = B; + L += 1; + WidthCounter -= 1; + } + Remaining -= 1; + } + break; + case 4: + for (i = 0; i < C; i++) { + if (WidthCounter > 0) { + *L = B >> 4; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = B & 15; + L += 1; + WidthCounter -= 1; + } + Remaining -= 1; + } + break; + case 2: + for (i = 0; i < C; i++) { + if (WidthCounter > 0) { + *L = (B >> 6) & 3; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 4) & 3; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 2) & 3; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = B & 3; + L += 1; + WidthCounter -= 1; + } + Remaining -= 1; + } + break; + case 1: + for (i = 0; i < C; i++) { + if (WidthCounter > 0) { + *L = (B >> 7) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 6) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 5) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 4) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 3) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 2) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = (B >> 1) & 1; + L += 1; + WidthCounter -= 1; + } + if (WidthCounter > 0) { + *L = B & 1; + L += 1; + WidthCounter -= 1; + } + Remaining -= 1; + } + break; + } } } else { - /* Just read one line */ - ReadData (F, L, P->Width); - + if (P->BPP == 4) { + printf("Not implemented\n"); + } else { + ReadData (F, L, P->Width); + } } } @@ -309,25 +403,42 @@ Bitmap* ReadPCXFile (const Collection* A) } } else { - /* One plane with 8bpp is indexed */ - for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { + if (P->BPP == 4) { + /* One plane with 8bpp is indexed */ + for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { - /* Read the plane */ - ReadPlane (F, P, L); + /* Read the plane */ + ReadPlane (F, P, L); - /* Create pixels */ - for (X = 0; X < P->Width; ++X, ++Px) { - if (L[X] > MaxIdx) { - MaxIdx = L[X]; + /* Create pixels */ + for (X = 0; X < P->Width; ++X, ++Px) { + if (L[X] > MaxIdx) { + MaxIdx = L[X]; + } + Px->Index = L[X]; + } + } + } else { + /* One plane with 8bpp is indexed */ + for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { + + /* Read the plane */ + ReadPlane (F, P, L); + + /* Create pixels */ + for (X = 0; X < P->Width; ++X, ++Px) { + if (L[X] > MaxIdx) { + MaxIdx = L[X]; + } + Px->Index = L[X]; } - Px->Index = L[X]; } } } /* One plane means we have a palette which is either part of the header - ** or follows. - */ + * or follows. + */ if (P->PalInfo == 0) { /* Create the monochrome palette */ From e953c1aa082a154b991388650bef4a0e46bd76b0 Mon Sep 17 00:00:00 2001 From: karri Date: Thu, 29 Dec 2022 19:28:16 +0200 Subject: [PATCH 02/11] Add support for 4 pixels per plane --- src/sp65/pcx.c | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index 489c65c5d..4beda045c 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -230,109 +230,109 @@ static void ReadPlane (FILE* F, PCXHeader* P, unsigned char* L) /* Write the data to the buffer */ switch (P->BPP) { default: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = B; + *L = B; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; case 4: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = B >> 4; + *L = B >> 4; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = B & 15; + *L = B & 15; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; case 2: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = (B >> 6) & 3; + *L = (B >> 6) & 3; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 4) & 3; + *L = (B >> 4) & 3; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 2) & 3; + *L = (B >> 2) & 3; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = B & 3; + *L = B & 3; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; case 1: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = (B >> 7) & 1; + *L = (B >> 7) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 6) & 1; + *L = (B >> 6) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 5) & 1; + *L = (B >> 5) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 4) & 1; + *L = (B >> 4) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 3) & 1; + *L = (B >> 3) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 2) & 1; + *L = (B >> 2) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 1) & 1; + *L = (B >> 1) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = B & 1; + *L = B & 1; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; - } + } } } else { /* Just read one line */ if (P->BPP == 4) { - printf("Not implemented\n"); - } else { + printf("Not implemented\n"); + } else { ReadData (F, L, P->Width); - } + } } } From 05766d4bfecddc4e4cd4d468c945ee142a5c163d Mon Sep 17 00:00:00 2001 From: karri Date: Thu, 29 Dec 2022 19:40:00 +0200 Subject: [PATCH 03/11] Add support for 4 pixels per plane --- src/sp65/pcx.c | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index 4beda045c..519f3bd58 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -230,109 +230,109 @@ static void ReadPlane (FILE* F, PCXHeader* P, unsigned char* L) /* Write the data to the buffer */ switch (P->BPP) { default: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = B; + *L = B; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; case 4: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = B >> 4; + *L = B >> 4; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = B & 15; + *L = B & 15; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; case 2: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = (B >> 6) & 3; + *L = (B >> 6) & 3; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 4) & 3; + *L = (B >> 4) & 3; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 2) & 3; + *L = (B >> 2) & 3; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = B & 3; + *L = B & 3; L += 1; WidthCounter -= 1; } Remaining -= 1; - } + } break; case 1: - for (i = 0; i < C; i++) { + for (i = 0; i < C; i++) { if (WidthCounter > 0) { - *L = (B >> 7) & 1; + *L = (B >> 7) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 6) & 1; + *L = (B >> 6) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 5) & 1; + *L = (B >> 5) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 4) & 1; + *L = (B >> 4) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 3) & 1; + *L = (B >> 3) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 2) & 1; + *L = (B >> 2) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = (B >> 1) & 1; + *L = (B >> 1) & 1; L += 1; WidthCounter -= 1; } if (WidthCounter > 0) { - *L = B & 1; + *L = B & 1; L += 1; WidthCounter -= 1; } Remaining -= 1; - } - break; } + break; + } } } else { /* Just read one line */ if (P->BPP == 4) { - printf("Not implemented\n"); - } else { + printf("Not implemented\n"); + } else { ReadData (F, L, P->Width); - } + } } } From 5ec5050af2cb6b9e51c3c5482aaf67be3f22c1d4 Mon Sep 17 00:00:00 2001 From: karri Date: Thu, 29 Dec 2022 21:48:28 +0200 Subject: [PATCH 04/11] Remove redundant code --- src/sp65/pcx.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index 519f3bd58..607253c59 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -403,35 +403,18 @@ Bitmap* ReadPCXFile (const Collection* A) } } else { - if (P->BPP == 4) { - /* One plane with 8bpp is indexed */ - for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { + /* One plane with 8bpp is indexed */ + for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { - /* Read the plane */ - ReadPlane (F, P, L); + /* Read the plane */ + ReadPlane (F, P, L); - /* Create pixels */ - for (X = 0; X < P->Width; ++X, ++Px) { - if (L[X] > MaxIdx) { - MaxIdx = L[X]; - } - Px->Index = L[X]; - } - } - } else { - /* One plane with 8bpp is indexed */ - for (Y = 0, Px = B->Data; Y < P->Height; ++Y) { - - /* Read the plane */ - ReadPlane (F, P, L); - - /* Create pixels */ - for (X = 0; X < P->Width; ++X, ++Px) { - if (L[X] > MaxIdx) { - MaxIdx = L[X]; - } - Px->Index = L[X]; + /* Create pixels */ + for (X = 0; X < P->Width; ++X, ++Px) { + if (L[X] > MaxIdx) { + MaxIdx = L[X]; } + Px->Index = L[X]; } } } From 9cb06672602c8d563d021baa7cdc3f871f67668f Mon Sep 17 00:00:00 2001 From: karri Date: Thu, 29 Dec 2022 21:53:50 +0200 Subject: [PATCH 05/11] Use same style in comments --- src/sp65/pcx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index 607253c59..18a60276d 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -153,10 +153,10 @@ static PCXHeader* ReadPCXHeader (FILE* F, const char* Name) P->Compressed, Name); } /* We support: - * - one plane with either 1, 4 or 8 bits per pixel - * - three planes with 8 bits per pixel - * - four planes with 8 bits per pixel (does this exist?) - */ + ** - one plane with either 1, 4 or 8 bits per pixel + ** - three planes with 8 bits per pixel + ** - four planes with 8 bits per pixel (does this exist?) + **/ if (!((P->BPP == 1 && P->Planes == 1) || (P->BPP == 4 && P->Planes == 1) || (P->BPP == 8 && (P->Planes == 1 || P->Planes == 3 || P->Planes == 4)))) { @@ -420,8 +420,8 @@ Bitmap* ReadPCXFile (const Collection* A) } /* One plane means we have a palette which is either part of the header - * or follows. - */ + ** or follows. + **/ if (P->PalInfo == 0) { /* Create the monochrome palette */ From ebd13810307768b422626d91253018e515d8ba06 Mon Sep 17 00:00:00 2001 From: karri Date: Thu, 29 Dec 2022 21:55:25 +0200 Subject: [PATCH 06/11] Use same style in comments --- src/sp65/pcx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sp65/pcx.c b/src/sp65/pcx.c index 18a60276d..e6d99b30b 100644 --- a/src/sp65/pcx.c +++ b/src/sp65/pcx.c @@ -156,7 +156,7 @@ static PCXHeader* ReadPCXHeader (FILE* F, const char* Name) ** - one plane with either 1, 4 or 8 bits per pixel ** - three planes with 8 bits per pixel ** - four planes with 8 bits per pixel (does this exist?) - **/ + */ if (!((P->BPP == 1 && P->Planes == 1) || (P->BPP == 4 && P->Planes == 1) || (P->BPP == 8 && (P->Planes == 1 || P->Planes == 3 || P->Planes == 4)))) { @@ -421,7 +421,7 @@ Bitmap* ReadPCXFile (const Collection* A) /* One plane means we have a palette which is either part of the header ** or follows. - **/ + */ if (P->PalInfo == 0) { /* Create the monochrome palette */ From 4117e94ed59e9a8c47f05eddad27bd746fba6d42 Mon Sep 17 00:00:00 2001 From: karri Date: Fri, 30 Dec 2022 14:44:18 +0200 Subject: [PATCH 07/11] Add palette extraction functions --- src/sp65/lynxpalette.c | 90 +++++++++++++++++++++++++++++++++++ src/sp65/lynxpalette.h | 66 ++++++++++++++++++++++++++ src/sp65/main.c | 64 +++++++++++++++++++++++-- src/sp65/palconv.c | 104 +++++++++++++++++++++++++++++++++++++++++ src/sp65/palconv.h | 72 ++++++++++++++++++++++++++++ 5 files changed, 391 insertions(+), 5 deletions(-) create mode 100644 src/sp65/lynxpalette.c create mode 100644 src/sp65/lynxpalette.h create mode 100644 src/sp65/palconv.c create mode 100644 src/sp65/palconv.h diff --git a/src/sp65/lynxpalette.c b/src/sp65/lynxpalette.c new file mode 100644 index 000000000..e822fa5ee --- /dev/null +++ b/src/sp65/lynxpalette.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* lynxpalette.c */ +/* */ +/* Lynx palette backend for the sp65 sprite and bitmap utility */ +/* */ +/* */ +/* */ +/* (C) 2022, Karri Kaksonen */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* common */ +#include "attrib.h" +#include "print.h" + +/* sp65 */ +#include "attr.h" +#include "error.h" +#include "palette.h" +#include "lynxpalette.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + +StrBuf* GenLynxPalette (const Bitmap* B, const Collection* A) +/* Generate binary output in Lynx palette format for the bitmap B. The output +** is stored in a string buffer (which is actually a dynamic char array) and +** returned. +** +*/ +{ + StrBuf* D; + Palette* P; + unsigned I; + + P = GetBitmapPalette (B); + D = NewStrBuf (); + for (I = 0; I < 16; ++I) { + + /* Get the color entry */ + const Color* C = P->Entries + I; + + /* Add the green component */ + SB_AppendChar (D, C->G >> 4); + } + for (I = 0; I < 16; ++I) { + + /* Get the color entry */ + const Color* C = P->Entries + I; + + /* Add the blue,red component */ + SB_AppendChar (D, (C->B & 0xF0) | (C->R >> 4)); + } + + /* Return the converted palette */ + return D; +} + diff --git a/src/sp65/lynxpalette.h b/src/sp65/lynxpalette.h new file mode 100644 index 000000000..3ba4526fb --- /dev/null +++ b/src/sp65/lynxpalette.h @@ -0,0 +1,66 @@ +/*****************************************************************************/ +/* */ +/* lynxpalette.h */ +/* */ +/* Lynx palette format backend for the sp65 sprite and bitmap utility */ +/* */ +/* */ +/* */ +/* (C) 2022, Karri Kaksonen */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef LYNXPALETTE_H +#define LYNXPALETTE_H + + + +/* common */ +#include "coll.h" +#include "strbuf.h" + +/* sp65 */ +#include "bitmap.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +StrBuf* GenLynxPalette (const Bitmap* B, const Collection* A); +/* Generate binary output in Lynx palette format for the bitmap B. The output + * is stored in a string buffer (which is actually a dynamic char array) and + * returned. + */ + + + +/* End of lynxpalette.h */ + +#endif + + + diff --git a/src/sp65/main.c b/src/sp65/main.c index 1dda696d6..62dec0952 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -1,6 +1,6 @@ /*****************************************************************************/ /* */ -/* main.c */ +/* main.c */ /* */ /* Main program of the sp65 sprite and bitmap utility */ /* */ @@ -47,6 +47,7 @@ /* sp65 */ #include "attr.h" #include "convert.h" +#include "palconv.h" #include "error.h" #include "input.h" #include "output.h" @@ -68,10 +69,13 @@ static Bitmap* C; /* Output data from convertion */ static StrBuf* D; +/* Output data from palconv */ +static StrBuf* E; + /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -88,11 +92,11 @@ static void Usage (void) " -lc\t\t\t\tList all possible conversions\n" " -r file[,attrlist]\t\tRead an input file\n" " -v\t\t\t\tIncrease verbosity\n" + " -p tgt,file[,attrlist]\t\tWrite the palette to a file\n" " -w file[,attrlist]\t\tWrite the output to a file\n" "\n" "Long options:\n" " --convert-to fmt[,attrlist]\tConvert into target format\n" - " --dump-palette\t\tDump palette as table\n" " --help\t\t\tHelp (this text)\n" " --list-conversions\t\tList all possible conversions\n" " --pop\t\t\t\tRestore the original loaded image\n" @@ -100,6 +104,7 @@ static void Usage (void) " --slice x,y,w,h\t\tGenerate a slice from the loaded bitmap\n" " --verbose\t\t\tIncrease verbosity\n" " --version\t\t\tPrint the version number and exit\n" + " --palette tgt,file[,attrlist]\tWrite the palette to a file\n" " --write file[,attrlist]\tWrite the output to a file\n", ProgName); } @@ -137,6 +142,21 @@ static void SetOutputData (StrBuf* N) } +static void SetPalOutputData (StrBuf* N) +/* Delete the old output data and replace it by the given one. The new one +** may be NULL to clear it. +*/ +{ + /* Delete the old output data */ + if (E != 0) { + FreeStrBuf (E); + } + + /* Set the new one */ + E = N; +} + + static void OptConvertTo (const char* Opt attribute ((unused)), const char* Arg) /* Convert the bitmap into a target format */ @@ -282,15 +302,45 @@ static void OptVerbose (const char* Opt attribute ((unused)), static void OptVersion (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Print the assembler version */ { fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); - exit(EXIT_SUCCESS); } +static void OptPalette (const char* Opt attribute ((unused)), const char* Arg) +/* Write an output file */ +{ + static const char* const NameList[] = { + "target", "name", "format" + }; + + + /* Parse the argument */ + Collection* A = ParseAttrList (Arg, NameList, 2); + + /* We must have a bitmap ... */ + if (C == 0) { + Error ("No bitmap"); + } + + /* ... which must be indexed */ + if (!BitmapIsIndexed (C)) { + Error ("Current bitmap is not indexed"); + } + + /* Convert the palette */ + SetPalOutputData (PaletteTo (C, A)); + + /* Write the file */ + WriteOutputFile (E, A, C); + + /* Delete the attribute list */ + FreeAttrList (A); +} + static void OptWrite (const char* Opt attribute ((unused)), const char* Arg) /* Write an output file */ { @@ -381,6 +431,10 @@ int main (int argc, char* argv []) OptVerbose (Arg, 0); break; + case 'p': + OptPalette (Arg, GetArg (&I, 2)); + break; + case 'w': OptWrite (Arg, GetArg (&I, 2)); break; diff --git a/src/sp65/palconv.c b/src/sp65/palconv.c new file mode 100644 index 000000000..e92f3c22e --- /dev/null +++ b/src/sp65/palconv.c @@ -0,0 +1,104 @@ +/*****************************************************************************/ +/* */ +/* palconv.c */ +/* */ +/* Color palette conversions for the sp65 sprite and bitmap utility */ +/* */ +/* */ +/* */ +/* (C) 2022, Karri Kaksonen */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include + +/* common */ +#include "check.h" +#include "xmalloc.h" + +/* sp65 */ +#include "attr.h" +#include "error.h" +#include "palette.h" +#include "lynxpalette.h" + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + +/* Type of the entry in the palette table */ +typedef struct PaletteMapEntry PaletteMapEntry; +struct PaletteMapEntry { + const char* Format; + StrBuf* (*PaletteFunc) (const Bitmap*, const Collection*); +}; + +/* Converter table, alphabetically sorted */ +static const PaletteMapEntry PaletteMap[] = { + { "lynx-palette", GenLynxPalette }, +}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + +static int Compare (const void* Key, const void* MapEntry) +/* Compare function for bsearch */ +{ + return strcmp (Key, ((const PaletteMapEntry*) MapEntry)->Format); +} + + + +StrBuf* PaletteTo (const Bitmap* B, const Collection* A) +/* Convert the palette of bitmap B into some sort of other binary format. +** The output is stored in a string buffer (which is actually a dynamic +** char array) and returned. The actual output format is taken from the +** "format" attribute in the attribute collection A. +*/ +{ + const PaletteMapEntry* E; + + /* Get the format to convert to */ + const char* Format = NeedAttrVal (A, "target", "palette"); + + /* Search for the matching converter */ + E = bsearch (Format, + PaletteMap, + sizeof (PaletteMap) / sizeof (PaletteMap[0]), + sizeof (PaletteMap[0]), + Compare); + if (E == 0) { + Error ("No such target format: '%s'", Format); + } + + /* Do the conversion */ + return E->PaletteFunc (B, A); +} + diff --git a/src/sp65/palconv.h b/src/sp65/palconv.h new file mode 100644 index 000000000..693281c20 --- /dev/null +++ b/src/sp65/palconv.h @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* */ +/* palconv.h */ +/* */ +/* Color palette conversions for the sp65 sprite and bitmap utility */ +/* */ +/* */ +/* */ +/* (C) 2022, Karri Kaksonen */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef PALCONV_H +#define PALCONV_H + + + +#include + +/* common */ +#include "coll.h" +#include "strbuf.h" + +/* sp65 */ +#include "bitmap.h" + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + +StrBuf* PaletteTo (const Bitmap* B, const Collection* A); +/* Convert the palette of bitmap B into some sort of other binary format. +** The output is stored in a string buffer (which is actually a dynamic char +** array) and returned. The actual output format is taken from the "target" +** attribute in the attribute collection A. +*/ + +void ListPaletteTargets (FILE* F); +/* Output a list of palette targets */ + +/* End of palette.h */ + +#endif + + + From f85951ab2497dec2bac535ae569382b20e89d9fe Mon Sep 17 00:00:00 2001 From: karri Date: Fri, 30 Dec 2022 15:06:22 +0200 Subject: [PATCH 08/11] Add to build --- src/sp65.vcxproj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sp65.vcxproj b/src/sp65.vcxproj index 1b7a18427..a9f0919a3 100644 --- a/src/sp65.vcxproj +++ b/src/sp65.vcxproj @@ -62,9 +62,11 @@ + + @@ -84,8 +86,10 @@ + + @@ -95,4 +99,4 @@ - \ No newline at end of file + From b6d06288e0e918dbad2b724caca5a2b0a4ba1e83 Mon Sep 17 00:00:00 2001 From: karri Date: Fri, 30 Dec 2022 15:20:54 +0200 Subject: [PATCH 09/11] Fix warnings --- src/sp65/lynxpalette.c | 7 +++++-- src/sp65/lynxpalette.h | 9 +++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sp65/lynxpalette.c b/src/sp65/lynxpalette.c index e822fa5ee..b084af26e 100644 --- a/src/sp65/lynxpalette.c +++ b/src/sp65/lynxpalette.c @@ -62,10 +62,13 @@ StrBuf* GenLynxPalette (const Bitmap* B, const Collection* A) */ { StrBuf* D; - Palette* P; + const Palette* P = GetBitmapPalette (B); + const char* Format = GetAttrVal(A, "format"); unsigned I; - P = GetBitmapPalette (B); + if (Format == 0) { + /* No format specified */ + } D = NewStrBuf (); for (I = 0; I < 16; ++I) { diff --git a/src/sp65/lynxpalette.h b/src/sp65/lynxpalette.h index 3ba4526fb..805db0d74 100644 --- a/src/sp65/lynxpalette.h +++ b/src/sp65/lynxpalette.h @@ -52,15 +52,12 @@ StrBuf* GenLynxPalette (const Bitmap* B, const Collection* A); /* Generate binary output in Lynx palette format for the bitmap B. The output - * is stored in a string buffer (which is actually a dynamic char array) and - * returned. - */ +** is stored in a string buffer (which is actually a dynamic char array) and +** returned. +*/ /* End of lynxpalette.h */ #endif - - - From 878a20ab59b8ba5104220dc4bcc08927816ae6d4 Mon Sep 17 00:00:00 2001 From: karri Date: Fri, 30 Dec 2022 15:27:17 +0200 Subject: [PATCH 10/11] Fix dangling space --- src/sp65/lynxpalette.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sp65/lynxpalette.h b/src/sp65/lynxpalette.h index 805db0d74..b4e3defe3 100644 --- a/src/sp65/lynxpalette.h +++ b/src/sp65/lynxpalette.h @@ -51,7 +51,7 @@ StrBuf* GenLynxPalette (const Bitmap* B, const Collection* A); -/* Generate binary output in Lynx palette format for the bitmap B. The output +/* Generate binary output in Lynx palette format for the bitmap B. The output ** is stored in a string buffer (which is actually a dynamic char array) and ** returned. */ From e2c6d06b0d5be4f77deb3994c601f362ae1326f1 Mon Sep 17 00:00:00 2001 From: karri Date: Wed, 4 Jan 2023 12:14:37 +0200 Subject: [PATCH 11/11] Update dosc --- doc/sp65.sgml | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/doc/sp65.sgml b/doc/sp65.sgml index 255d7a552..e1bcdd558 100644 --- a/doc/sp65.sgml +++ b/doc/sp65.sgml @@ -44,6 +44,7 @@ Short options: -lc List all possible conversions -r file[,attrlist] Read an input file -v Increase verbosity + -p tgt,file[,attrlist] Write the palette to a file -w file[,attrlist] Write the output to a file Long options: @@ -56,6 +57,7 @@ Long options: --slice x,y,w,h Generate a slice from the loaded bitmap --verbose Increase verbosity --version Print the version number and exit + --palette tgt,file{,attrlist] Write the palette to a file --write file[,attrlist] Write the output to a file --------------------------------------------------------------------------- @@ -124,6 +126,13 @@ attribute lists see . bugfixes, please include the version number. +