Image quantization for imagecon

This commit is contained in:
alpine9000 2016-03-01 17:23:31 +11:00
parent 6ee792e561
commit 92d0b97d85
7 changed files with 89 additions and 51 deletions

View File

@ -1,7 +1,7 @@
MAKEADF=../tools/makeadf
FLOPPY=bin/image.adf
EXTRA=out/image-copper-list.s out/image.bin
IMAGEFILE=../assets/hello.png
IMAGEFILE=../assets/mission-beach.png
MODULE=image.s

View File

@ -94,3 +94,14 @@ Notes:
# make
# make install
```
7. pngquant
```
# git clone git://github.com/pornel/pngquant.git
# cd pngquant/lib
# ./configure --prefix=/usr/local
# make
# mkdir /usr/local/include/pngquant
# cp *.h /usr/local/include/pngquant/
# cp *.a /usr/local/lib
```

BIN
assets/mission-beach.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -1,6 +1,6 @@
IMAGECON=./bin/imagecon
SRCS=imagecon.c
HOST_WARNINGS=-pedantic-errors -Wfatal-errors -Wall -Werror -Wextra -Wno-unused-parameter -Wshadow
HOST_WARNINGS=-pedantic-errors -Wfatal-errors -Wall -Werror -Wextra -Wno-unused-parameter -Wshadow -limagequant
HOST_CFLAGS=$(HOST_WARNINGS)
imagecon: out bin $(SRCS)
@ -15,7 +15,7 @@ bin:
bitplane.bin copper-list.s: bin/imagecon
$(IMAGECON) ../../assets/hello.png out/hello
test: bitplane.bin copper-list.s
test: imagecon bitplane.bin copper-list.s
diff out/hello.bin reference/bitplane.bin
diff out/hello-copper-list.s reference/copper-list.s

View File

@ -16,6 +16,8 @@
#define PNG_DEBUG 3
#include <png.h>
#include <pngquant/libimagequant.h>
char** _argv;
void
@ -42,7 +44,7 @@ typedef struct {
amiga_color_t palette[MAX_PALETTE];
int paletteIndex = 0;
unsigned* amigaImage = 0;
unsigned char* amigaImage = 0;
void readFile(char* file_name)
{
@ -143,42 +145,67 @@ void readFile(char* file_name)
void
processFile(char* outFilename)
{
amigaImage = calloc(width*height, 4);
int numColors;
amigaImage = calloc(width*height, 1);
for (int y=0; y<height; y++) {
png_byte* row = rowPointers[y];
for (int x=0; x<width; x++) {
png_byte* ptr = &(row[x*4]);
amiga_color_t color;
color.r = ptr[0] >> 4;
color.g = ptr[1] >> 4;
color.b = ptr[2] >> 4;
if (1) {
liq_attr *attr = liq_attr_create();
// liq_image *image = liq_image_create_rgba(attr, rowPointers, width, height, 0);
liq_image *image = liq_image_create_rgba_rows(attr, (void**)rowPointers, width, height, 0);
liq_set_max_colors(attr, 16);
liq_set_speed(attr, 1);
liq_result *res = liq_quantize_image(attr, image);
liq_write_remapped_image(res, image, amigaImage, width*height);
const liq_palette *pal = liq_get_palette(res);
printf("pal->count = %d\n", pal->count);
int index = -1;
for (int i = 0; i < paletteIndex; i++) {
if (memcmp(&palette[i], &color, sizeof(amiga_color_t)) == 0) {
index = i;
break;
}
}
if (index == -1 && paletteIndex < MAX_PALETTE) {
index = paletteIndex;
paletteIndex++;
} else if (index == -1 && paletteIndex == MAX_PALETTE) {
abort_("Too many colors\n");
}
palette[index] = color ;
amigaImage[(width*y)+x] = index;
for (unsigned i = 0; i < pal->count; i++) {
printf("%d %d %d %d\n", i, pal->entries[i].r, pal->entries[i].g, pal->entries[i].b);
palette[i].r = pal->entries[i].r >> 4;
palette[i].g = pal->entries[i].g >> 4;
palette[i].b = pal->entries[i].b >> 4;
}
numColors = pal->count;
} else {
for (int y=0; y<height; y++) {
png_byte* row = rowPointers[y];
for (int x=0; x<width; x++) {
png_byte* ptr = &(row[x*4]);
amiga_color_t color;
color.r = ptr[0] >> 4;
color.g = ptr[1] >> 4;
color.b = ptr[2] >> 4;
int index = -1;
for (int i = 0; i < paletteIndex; i++) {
if (memcmp(&palette[i], &color, sizeof(amiga_color_t)) == 0) {
index = i;
break;
}
}
if (index == -1 && paletteIndex < MAX_PALETTE) {
index = paletteIndex;
paletteIndex++;
} else if (index == -1 && paletteIndex == MAX_PALETTE) {
abort_("Too many colors\n");
}
palette[index] = color ;
amigaImage[(width*y)+x] = index;
}
}
numColors = paletteIndex;
}
int numColors = paletteIndex-1;
int numBitPlanes = (int)(log(numColors) / log(2))+1;
int numBitPlanes = (int)(log(numColors-1) / log(2))+1;
printf("number of colors = %d\n", numColors);
printf("number of bitplanes = %d\n", numBitPlanes);
@ -190,7 +217,7 @@ processFile(char* outFilename)
abort_("failed to open %s for writing", filenameBuffer);
}
for (int i = 0; i < paletteIndex; i++) {
for (int i = 0; i < numColors; i++) {
printf("%d: %x %d %d %d\n", i , palette[i].r << 8 | palette[i].g << 4 | palette[i].b, palette[i].r, palette[i].g, palette[i].b);
fprintf(fp, "\tdc.w $%x,$%x\n", 0x180+(i*2), palette[i].r << 8 | palette[i].g << 4 | palette[i].b);
}

View File

@ -1,16 +1,16 @@
dc.w $180,$fff
dc.w $182,$ee9
dc.w $184,$ddd
dc.w $186,$fe0
dc.w $188,$fa7
dc.w $18a,$9dc
dc.w $18c,$f92
dc.w $18e,$2b5
dc.w $190,$e20
dc.w $192,$e9a
dc.w $194,$b0
dc.w $196,$d12
dc.w $198,$1ae
dc.w $19a,$6a
dc.w $19c,$744
dc.w $19e,$362
dc.w $182,$1ae
dc.w $184,$e20
dc.w $186,$d12
dc.w $188,$fe0
dc.w $18a,$b0
dc.w $18c,$ddd
dc.w $18e,$6a
dc.w $190,$9dc
dc.w $192,$362
dc.w $194,$2b5
dc.w $196,$f92
dc.w $198,$ee9
dc.w $19a,$e9a
dc.w $19c,$fa7
dc.w $19e,$744