diff --git a/osufs/osufs/imgenc.c b/osufs/osufs/imgenc.c index 66f3163d9f94c3bcb169efeadd427f546fe8ae58..46c89d6b0e40ad17c5afbdbea272a7247101d54a 100644 --- a/osufs/osufs/imgenc.c +++ b/osufs/osufs/imgenc.c @@ -80,7 +80,86 @@ uint32_t img_write_dither128(const char *filename, mdev *dev, uint32_t addr) { return addr; } -uint32_t img_write_rgb16(const char *filename, mdev *dev, uint32_t addr, uint16_t *w, uint16_t *h) { +uint32_t img_write_dither64(const char *filename, mdev *dev, uint32_t addr, + uint16_t *w, uint16_t *h) { + char cbuf[1024]; + int ret; + + int w_signed = *w==0xffff ? -1 : *w, h_signed = *h==0xffff ? -1 : *h; + + system("rm -f /tmp/source.png /tmp/plt.png /tmp/dither.png"); + + // Resize + sprintf(cbuf, "ffmpeg -loglevel error -i \"%s\" -vf \"scale=%d:%d\" /tmp/source.png", filename, w_signed, h_signed); + ret = system(cbuf); + if (ret != 0) { + fprintf(stderr, "ffmpeg resize failed with exit code: %d\n", ret); + return addr; + } + + // PaletteGen + ret = system("ffmpeg -loglevel error -i /tmp/source.png -vf \"palettegen=max_colors=64\" /tmp/plt.png"); + if (ret != 0) { + fprintf(stderr, "ffmpeg palettegen failed with exit code: %d\n", ret); + return addr; + } + + // Dithering + ret = system("ffmpeg -loglevel error -i /tmp/source.png -i /tmp/plt.png -lavfi \"paletteuse=dither=floyd_steinberg\" -y /tmp/dither.png"); + if (ret != 0) { + fprintf(stderr, "ffmpeg dithering failed with exit code: %d\n", ret); + } + + + PNGImage img = pngimg_read("/tmp/dither.png"); + if (img.color_type != PNG_COLOR_TYPE_PALETTE) { + fprintf(stderr, "Internal Error: dithered image is not index!\n"); + return addr; + } + + png_colorp plt; + int nplt; + if (!png_get_PLTE(img.png_ptr, img.info_ptr, &plt, &nplt)) { + fprintf(stderr, "Internal Error: failed to read palette!\n"); + return addr; + } + + // Dump palette + uint8_t buf[512], *pltbuf = buf + 3; + buf[0] = 'P'; + buf[1] = 'L'; + buf[2] = 'T'; + for (int i=0; i<64; i++) { + pltbuf[i*3+0] = plt[0xff-i].red; + pltbuf[i*3+1] = plt[0xff-i].green; + pltbuf[i*3+2] = plt[0xff-i].blue; + } + blkio_write(dev, addr++, buf); + + // Dump image, row major + *w = img.width; + *h = img.height; + printf("Saving pixels in %s\n", filename); + size_t bufsize = png_get_rowbytes(img.png_ptr, img.info_ptr) * img.height; + size_t bufptr = 0; + uint8_t *pixbuf; + while (bufsize > 0) { + pixbuf = img.row_pointers[0]+bufptr; + for (int i=0; i<512; i++) { + pixbuf[i] = 0xff - pixbuf[i]; + } + blkio_write(dev, addr++, pixbuf); + bufptr += 512; + bufsize -= 512; + } + + pngimg_release(&img); + + return addr; +} + +uint32_t img_write_rgb16(const char *filename, mdev *dev, uint32_t addr, + uint16_t *w, uint16_t *h) { char cbuf[1024]; int ret; diff --git a/osufs/osufs/imgenc.h b/osufs/osufs/imgenc.h index 1f49ea13d561d890a627f56b3a5651d3c3befda2..f0a0e948708398d20c34e233e81df70dee0cec0f 100644 --- a/osufs/osufs/imgenc.h +++ b/osufs/osufs/imgenc.h @@ -17,7 +17,10 @@ extern "C" { #include "blkio.h" uint32_t img_write_dither128(const char *filename, mdev *dev, uint32_t addr); - uint32_t img_write_rgb16(const char *filename, mdev *dev, uint32_t addr, uint16_t *w, uint16_t *h); + uint32_t img_write_dither64(const char *filename, mdev *dev, uint32_t addr, + uint16_t *w, uint16_t *h); + uint32_t img_write_rgb16(const char *filename, mdev *dev, uint32_t addr, + uint16_t *w, uint16_t *h); #ifdef __cplusplus } diff --git a/osufs/osufs/osu.cpp b/osufs/osufs/osu.cpp index 839798e5d3cc5acdd32effa3a93b8b5de3467ebc..9823a58b6529dd8932eaf5a1df62a216ac1888b7 100644 --- a/osufs/osufs/osu.cpp +++ b/osufs/osufs/osu.cpp @@ -39,6 +39,13 @@ meta-> entry ## _w = w;\ meta-> entry ## _h = h;\ addr = img_write_rgb16(cbuf, dev, addr, &(meta-> entry ## _w), &(meta-> entry ## _h)); +#define SKIN_IMPORT_IMAGE_DITHER64(entry, filename, w, h)\ +strcpy(fname, filename);\ +meta-> entry = addr;\ +meta-> entry ## _w = w;\ +meta-> entry ## _h = h;\ +addr = img_write_dither64(cbuf, dev, addr, &(meta-> entry ## _w), &(meta-> entry ## _h)); + char cbuf[1024], *fname; uint32_t addr = meta->available_block; @@ -98,16 +105,16 @@ addr = img_write_rgb16(cbuf, dev, addr, &(meta-> entry ## _w), &(meta-> entry ## SKIN_IMPORT_IMAGE(pause_continue, "pause-continue.png", 235, -1) SKIN_IMPORT_IMAGE(pause_retry, "pause-retry.png", 235, -1) - SKIN_IMPORT_IMAGE(ranking_ss, "ranking-X.png", 160, -1) - SKIN_IMPORT_IMAGE(ranking_s, "ranking-S.png", 160, -1) - SKIN_IMPORT_IMAGE(ranking_a, "ranking-A.png", 160, -1) - SKIN_IMPORT_IMAGE(ranking_b, "ranking-B.png", 160, -1) - SKIN_IMPORT_IMAGE(ranking_c, "ranking-C.png", 160, -1) - SKIN_IMPORT_IMAGE(ranking_d, "ranking-D.png", 160, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_ss, "ranking-X.png", 160, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_s, "ranking-S.png", 160, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_a, "ranking-A.png", 160, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_b, "ranking-B.png", 160, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_c, "ranking-C.png", 160, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_d, "ranking-D.png", 160, -1) + + SKIN_IMPORT_IMAGE_DITHER64(ranking_title, "ranking-title.png", 240, -1) + SKIN_IMPORT_IMAGE_DITHER64(ranking_panel, "ranking-panel.png", 378, -1) -// SKIN_IMPORT_IMAGE(ranking_title, "ranking-title.png", 240, -1) -// SKIN_IMPORT_IMAGE(ranking_panel, "ranking-panel.png", 378, -1) - meta->selection_w = 48; meta->selection_h = 56; meta->selection_mod = addr;