mateoconlechuga / convimg Goto Github PK
View Code? Open in Web Editor NEWImage palette quantization
License: BSD 3-Clause "New" or "Revised" License
Image palette quantization
License: BSD 3-Clause "New" or "Revised" License
ConvPNG gives an error when you put too much data in an appvar, for example 70kB, even though the compression flag is set.
Convimg does not contain a command that will allow the user to output a particular string header at the start of an Appvar. This would allow programs to easily search for an Appvar using Detect(). This was a command convPNG included but convIMG does not.
I want to rewrite convpng in Rust.
This is just a reminder to myself. Try a light gray color?
The code is getting hard to read. I need to listen to my own advice and keep it simple stupid.
dir/*/*_3 for example should find all of it man.
Trying to convert a tileset results in the tileset image being treated like a regular sprite.
The relevant part of my config file:
tilesets:
tile-width: 14
tile-height: 5
ptable: true
images:
- tileset.png
Based on the output, I think this is a parser issue - I think the images
line causes the parser to exit the tileset mode. However, removing that line causes convimg to quit with [error] Failed to load image '(null)'
So, I have been struggling with one sprite that seems to be corrupt after compression/encoding.
In earlier builds, it would crash in Cemu, with the Console suggesting "null pointer dereference".
I fixed that with difficulty, and the program no longer crashes, but the sprite renders garbage. Exiting the faulty screen corrupts the background.
Relevant Code from my Project: https://pastebin.com/j54gn3Un
Convpng.ini: https://pastebin.com/RPk2Kps4
Image in question: https://imgur.com/a/iGLWhnn
Animation Showing Error: http://clrhome.org/startrek/temp/corrupt_show.png
If I have an image named 1.png, the array that is created is named '1', which isn't a valid array name. This also affects macros.
This is related to #37 that I proposed a while back. In my specific project, my appvar is compressed, and the trekgui_init code looks like this.
bool trekgui_init(void *decompressed_addr) {
unsigned int data, i;
data = (unsigned int)decompressed_addr - (unsigned int)trekgui[0];
for (i = 0; i < trekgui_num; i++) {
trekgui[i] += data;
}
return (bool)appvar;
}
This is wrong because in this particular case, appvar does not exist. I propose fixing by mixing this with the code to open (and decompress) the appvar.
bool trekgui_init(void *decompressed_addr) {
unsigned int data, i;
ti_var_t appvar;
appvar = ti_Open("trekgui", "r");
zx7_Decompress(decompressed_addr, ti_GetDataPtr(appvar));
data = (unsigned int)decompressed_addr - (unsigned int)trekgui[0];
for (i = 0; i < trekgui_num; i++) {
trekgui[i] += data;
}
ti_Close(appvar); // ti_CloseAll()
return (bool)appvar;
}
Offsets after 255 images are set to 0, despite having 'enough' space, i.e. offset is 45K.
In order to fix a missing glob.h
issue on some windows builds, something like this from @jacobly0 should probably be implemented here in parser.c
.
Seems like an off-by-one issue
When using fixed-colors
in a palette, a particular color can be chosen for the palette twice, once as the fixed color, and again as a quantized palette entry. This can be wasteful, especially for low bpp modes or with dynamic palettes.
Perhaps any pixels that exactly match a fixed color could be removed from the image when generating the quantized palette.
When trying to create a palette with no images, convimg gives the error [error] No images to convert for palette 'night'
. It would be useful if you could generate a palette from only fixed index colors. I use this for dynamic palettes so that I don't need multiple copies of sprites in different colors, and currently, I have to include a "dummy" image to get the palette to generate.
When I export an appvar, the order of the images in the .inc
file is not the same as the actual order in the appvar.
For example, the file a/abcd.png
is written as a/a.h
, and abc/abcd.png
is written as abc.h
.
Rather than a name; it would be nice if convpng supported wildcards and relative/absoulte paths you know :P
[20:56:30] <Kryptonic> What's the point of having the color that was used to indicate a transparent pixel in the palette if using RLET sprites?
[20:59:58] <Pieman> What is the point of RLET sprites?
[21:00:06] <saxjax> [epsilon5] Compression.
[21:03:38] <Kryptonic> I'm trying to get convpng to make a palette that doesn't include the color I'm using to indicate transparency in rlet sprites, but I don't know if that makes sense and/or is possible
[21:04:25] <MateoC> that does make sense I guess
[21:04:46] <MateoC> maybe make an issue for it :P
[21:05:18] <Kryptonic> So like, I'm doing kinda what Oiram does where it has multiple recipes, on at the very top that simply makes a palette using all the images in the folder, and the all the other recipes are told to use that generated palette
[21:05:54] <MateoC> sure
[21:06:08] <MateoC> I think that convpng needs another rewrite
ConvImg Appvar is broken. Mateo sent me here.
Um yeah that thing...
[2017-04-30 10:46:42] <Runer112> speaking of convpng
[2017-04-30 10:47:00] <Runer112> did you ever create the fast transparent sprite conversion
[2017-04-30 10:48:24] <MateoC> oops
[2017-04-30 10:48:26] <MateoC> No :P
[2017-04-30 10:48:46] <Runer112> I recently rediscovered my attempts to create that routine
[2017-04-30 10:48:52] <Runer112> I think the unclipped version is actually done
[2017-04-30 10:49:02] <Runer112> would be nice to test i
[2017-04-30 10:49:10] <MateoC> Okay :)
[2017-04-30 10:49:18] โ MateoC gets out the logs to find the format
[2017-04-30 10:49:55] <Runer112> each row is just an alternating sequence
[2017-04-30 10:50:03] <Runer112> trans run length, opaque run length + data
[2017-04-30 10:50:15] <Runer112> always starts with trans
[2017-04-30 10:50:39] <Runer112> (so if the row actually starts opaque, just emit a 0 for the first trans run length)
[2017-04-30 10:50:58] <MateoC> Okay :)
[2017-04-30 10:51:05] <MateoC> Just normal rle?
[2017-04-30 10:51:16] <Runer112> not normal RLE, no
[2017-04-30 10:51:22] <Runer112> but similar
[2017-04-30 10:51:34] <MateoC> Got it
[2017-04-30 10:51:51] <Runer112> basically, the "run" has no value associated with it
[2017-04-30 10:52:00] <Runer112> it's a meta transparent run
How to do this...
Currently, when you use #Palette
, both #TransparentColor
and #TransparentIndex
are ignored. It seems right to me that at least #TransparentIndex
would be supported when using #Palette
as well.
I used the latest convpng.ini from AoCE, but with this: Buildings/*/*_{1,2,3,4}.png
instead of
Buildings/*/*_1.png
Buildings/*/*_2.png
Buildings/*/*_3.png
Buildings/*/*_4.png
No idea what went wrong :P
So, as you know convpng has the option to Compress individual sprites, or the entire block of sprite data in the appvar. When using the former, it would obviously be simple to use, as decompressing the appvar returns a nicely formatted array of sprites, which the _init() routine can then read. The problem is that when #Compression is used in the #appvarc group, there is no decompressed data size to help with malloc'ing a buffer for decompression. While this can be done by hand using the image sizes, convpng seems designed to set things up nicely for you, so this is something that should be included... #define the decompressed buffer size if #compression is specified in the appvarc block in convpng.ini.
The ability to ouput in ICE format would be quite handy. It is simply a string of the array with no spaces or padding:
"0101FFFFFF...."
The first two bytes represent the width/height of the sprite respectively.
I want to convert these images, but sometimes ConvPNG crashes, although I dunno when/why ;)
There should be a convert option for rotating and mirroring input images. It would be useful for alternate SPI modes, which can use a column-major memory layout.
I have been working on a library called ICERGB, which uses the full 65,636 colors.
It would be nice if you could make convpng have the ability to create sprites/images capable of displaying in 16-bit color mode.
rgb > 1555 (or 565) > rgb
, then quantize.
Sorry to make this issue again, but converting AoCE graphics still crashes, either after converting the buildings or after exporting the appvars. I use your ConvPNG and my own one but both are crashing.
Can we please fix appvar exportation and add something to the toolchain to make it easy to read things? Thanks.
When exporting to appvars (I think it only fits with ASM appvars), add an option to output all the defines in a seperate .inc file, so for each image x_width and x_height, and preferable the offset too, so sprite 1 would have offset sprite0_height * sprite0_width + 2
if you get what I mean. This would help a lot if you have a game which loads the sprites from an appvar, but you don't want to manually set the sprite heights and widths, and offsets. :)
Issue posted as requested: Noticed that when you export sprites to an appvar, you lose the width and height defines for the sprite. These should remain.
Hm. Need to think on this.
Edit: this is caused by issue #4
For example, the command
convpng -8zjh -i 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png 11.png 12.png 13.png 14.png
puts all of the images in a file and calls it 1.h, but leaves:
macros in between every image.
In the attached directory, max-entries does not limit the number of entries in the palette.
convimg-test-3.zip
You should be able to specify a name when defining a fixed palette value, which would be added to the group header as a define for that index. This would prevent the need for magic values when using fixed palette indexes.
For example, adding #FixedIndexColor: 2, 255, 255, 255, WHITE
to a group named "gfx_group" in convpng.ini would add the line #define GFX_GROUP_WHITE 2
to gfx_group.h. You could then use gfx_SetColor(GFX_GROUP_WHITE);
or similar.
Title is self-explanatory.
Program displays author info, and then hangs. No convpng.log created, no terminal output.
I don't expect this to an easy fix or a priority one, but I have included the build directory as it was on my Pi, with the build files and output included, in case any of that helps with debugging.
convpng-master.zip
According to the YAML spec,
The content of a mapping node is an unordered set of key: value node pairs, with the restriction that each of the keys is unique.
In convimg, in order to specify multiple outputs, palettes, converts, or fixed index colors, keys with duplicate values must be used, in violation of the spec.
For example, the following is a valid input for convimg, but not a valid YAML file:
output: c
palettes:
- palette1
- palette2
converts:
- convert1
- convert2
output: ice
palettes:
- palette1
- palette2
converts:
- convert1
- convert2
palette: palette1
images: automatic
fixed-color: {index: 0, r: 255, g: 255, b: 255}
fixed-color: {index: 1, r: 0, g: 0, b: 0}
palette: palette2
images: automatic
fixed-color: {index: 0, r: 0, g: 0, b: 0}
fixed-color: {index: 1, r: 255, g: 255, b: 255}
convert: convert1
palette: palette1
images:
- *
convert: convert2
palette: palette2
images:
- *
This could be fixed by replacing the mappings that use duplicate keys with a mapping of selections for each key type, as in the following example:
outputs:
- type: c
palettes:
- palette1
- palette2
converts:
- convert1
- convert2
- type: ice
palettes:
- palette1
- palette2
converts:
- convert1
- convert2
palettes:
- name: palette1
images: automatic
fixed-colors:
- {index: 0, r: 255, g: 255, b: 255}
- {index: 1, r: 0, g: 0, b: 0}
- name: palette2
images: automatic
fixed-color: {index: 0, r: 0, g: 0, b: 0}
fixed-color: {index: 1, r: 255, g: 255, b: 255}
converts:
- name: convert1
palette: palette1
images:
- *
- name: convert2
palette: palette2
images:
- *
Title roughly explains the feature request. With this functionality, an input color must exactly match the specified color. This is useful in the case that a special input color maps to a palette color that may be changed dynamically at runtime. In this case, non-special pixels that may have similar input colors should not be mapped to this special color.
Suggested implementation: remove the seemingly unnecessary optional "alpha" parameter of #FixedIndexColor
and replace it with an optional "exact match" boolean parameter, to trigger the new functionality.
Alternate implementation: create a new instruction #FixedIndexColorExact
with the same parameters as #FixedIndexColor
to provide the new functionality.
This is the right place to post this 'issue' :P
So basically, an option that you can ignore/remove the transparent pixels in the output, thus that you don't get a rectangular output in general. Is useful for people who use their own routine to display a non-rectangular sprite (like me).
When giving a black-and-white 5x7 sprite to convimg, it only creates one index in global_palette.c (as opposed to two indices). When trying to display the sprite on the screen, it outputs a 5x7 black box instead of what the sprite looks like. Sprite I used can be found here.
Using a 320x240 image and this convimg.yaml I end up with a weird behavior where convimg is adding illegal semicolons to the end of functions in the C code.
convimg.yaml:
output: appvar
include-file: var_gfx.h
name: var_gfx
source-format: c
palettes:
- tiles_gfx
converts:
- tileset
palette: tiles_gfx
images: automatic
convert: tileset
palette: tiles_gfx
tilesets: {tile-width:80, tile-height:80}
compress: zx7
- tileset.png
var_gfx.c:
#include "var_gfx.h"
#include <fileioc.h>
unsigned char *var_gfx_appvar[2] =
{
(unsigned char*)0,
(unsigned char*)176,
};
unsigned char *tileset_tiles_compressed[12] =
{
(unsigned char*)0,
(unsigned char*)307,
(unsigned char*)1644,
(unsigned char*)2870,
(unsigned char*)3053,
(unsigned char*)3840,
(unsigned char*)4738,
(unsigned char*)6021,
(unsigned char*)6451,
(unsigned char*)7029,
(unsigned char*)8642,
(unsigned char*)10278,
};
unsigned char var_gfx_init(void)
{
unsigned int data, i;
ti_var_t appvar;
ti_CloseAll();
appvar = ti_Open("var_gfx", "r");
if (appvar == 0)
{
return 0;
}
data = (unsigned int)ti_GetDataPtr(appvar) - (unsigned int)var_gfx_appvar[0];
for (i = 0; i < 2; i++)
{
var_gfx_appvar[i] += data;
}
ti_CloseAll();
data = (unsigned int)var_gfx_appvar[1] - (unsigned int)tileset_tiles_compressed[0];
for (i = 0; i < tileset_tiles_num; i++)
{
tileset_tiles_compressed[i] += data;
}
return 1;
}; // This right here is what I am talking about
While it can be manually corrected it is still rather annoying and I figured was worth reporting.
When you set #OutputDirectory
to something like test
, which would put the .asm files in the folder test
, ConvPNG does create the .asm files, but only the header in it, not the actual data, something like this:
; Converted using ConvPNG
and 2 empty lines; nothing more. I've tested this with #GroupASM
in case that might help.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.