Trying to create a colormap for a PNG8
Posted: 2009-11-09T20:42:27-07:00
Hi all. I've been struggling today to try to get this code working. It's failing now on creation of any colormap entries other than index 0. Truecolor, truecolor with transparency work. The transparency channel of PNG8 seems to work. but I can't fill colormap entries other than entry 0 using MagickSetImageColormapColor() Any help or suggestions would be appreciated. Apologies for the organization of the code. I plan on getting it working first, then cleaning it up...
I think i need to set the number of colors for the colormap, but i can't figure out what call does this. (??)
The two parameters are image structures that contain width, height, and a data array of N pixels, where a pixel has 4 8-bit components, red, green, blue, and index. Both RGB and Index are populated with correct data. palette is simply an image of N pixels where each pixel is a palette color.
I think i need to set the number of colors for the colormap, but i can't figure out what call does this. (??)
The two parameters are image structures that contain width, height, and a data array of N pixels, where a pixel has 4 8-bit components, red, green, blue, and index. Both RGB and Index are populated with correct data. palette is simply an image of N pixels where each pixel is a palette color.
Code: Select all
void
PNG_Save (
char * filename, /* filename to save out to */
IMAGE * tosave, /* the image to save */
IMAGE * palette /* a palette disguised as an image - null if truecolor */
)
{
FILE * fp = NULL;
int width, height;
if( tosave == NULL ) {
fprintf( stderr, "Nothing to save.\n" );
return;
}
height = tosave->height;
width = tosave->width;
if( width == 0 || height == 0)
{
fprintf(stderr, "%dx%d: Illegal image dimensions\n",
tosave->width, tosave->height);
return;
}
fp = LS_WritableOpen( filename );
if( !fp || tosave == NULL || filename == NULL)
{
if( fp ) fclose(fp);
printf("Didn't saved nothing.\n");
return;
}
fclose( fp );
do {
MagickWand *image_wand;
MagickBooleanType status;
PixelWand * aColor;
PixelWand **pixels;
PixelIterator *iterator;
int x,y;
unsigned long nw;
MagickWandGenesis();
image_wand = NewMagickWand();
aColor = NewPixelWand();
PixelSetColor( aColor, "black" );
/* create our image */
status = MagickNewImage( image_wand, (int)width, (int)height, aColor );
printf( "MagickNewImage %s\n", status?"TRUE":"false" );
status = MagickSetImageColorspace( image_wand, RGBColorspace );
printf( "MagickSetImageColorspace %s\n", status?"TRUE":"false" );
status = MagickSetImageDepth( image_wand, 8 );
printf( "MagickSetImageDepth %s\n", status?"TRUE":"false" );
status = MagickSetImageChannelDepth( image_wand, AllChannels, 8 );
printf( "MagickSetImageChannelDepth %s\n", status?"TRUE":"false" );
/* set the appropriate image format */
if( palette ) {
status = MagickSetImageFormat( image_wand, "PNG8" );
printf( "MagickSetImageFormat %s\n", status?"TRUE":"false" );
if( ti->up->trn ) {
status = MagickSetImageType( image_wand, PaletteMatteType );
printf( "MagickSetImageType PaletteMatteType %s\n", status?"TRUE":"false" );
} else {
status = MagickSetImageType( image_wand, PaletteType );
printf( "MagickSetImageType PaletteType %s\n", status?"TRUE":"false" );
}
} else {
status = MagickSetImageFormat( image_wand, "PNG32" );
printf( "MagickSetImageFormat %s\n", status?"TRUE":"false" );
if( ti->up->trn ) {
status = MagickSetImageType( image_wand, TrueColorMatteType );
printf( "MagickSetImageType TrueColorMatteType %s\n", status?"TRUE":"false" );
} else {
status = MagickSetImageType( image_wand, TrueColorType );
printf( "MagickSetImageType TrueColorType %s\n", status?"TRUE":"false" );
}
}
printf( "MagickSetImageType %s\n", status?"TRUE":"false" );
/* set up the palette - fails if before or after the image buffer stuff */
if( palette ) {
int cmapidx = 0;
for( y=0 ; y<palette->height ; y++ )
{
for( x=0 ; x<palette->width ; x++ )
{
PixelWand * pw = NewPixelWand(); /* trying to create a new pixel wand each time. doesn't help. */
int ppos = (y*palette->width) + x;
int r = palette->data[ppos].r;
int g = palette->data[ppos].g;
int b = palette->data[ppos].b;
PixelSetRed( pw, r );
PixelSetGreen( pw, g );
PixelSetBlue( pw, b );
/*PixelSetIndex( aColor, cmapidx ); */
status = MagickSetImageColormapColor( image_wand, cmapidx, pw );
printf( "%s %d: %d %d %d\n", status==MagickTrue?"OK":"BAD", cmapidx, r, g, b );
cmapidx++;
DestroyPixelWand( pw );
}
}
}
/* iterate over the loaded png, and shove it into our user buf */
iterator = NewPixelIterator( image_wand );
if( iterator == (PixelIterator *) NULL) {
/* fail */
fprintf( stderr, "Couldn't access pixels. Fail.\n" );
} else {
for( y=0 ; y<height ; y++ )
{
pixels = PixelGetNextIteratorRow( iterator, &nw );
if( pixels == (PixelWand **)NULL) break;
for( x=0 ; x<nw ; x++ )
{
int dpos = (y * width) + x;
int r = tosave->data[dpos].r;
int g = tosave->data[dpos].g;
int b = tosave->data[dpos].b;
int idx = tosave->data[dpos].idx;
if( palette ) {
PixelSetIndex( pixels[x], idx );
} else {
PixelSetRed( pixels[x], r );
PixelSetGreen( pixels[x], g );
PixelSetBlue( pixels[x], b );
}
/* set transparency */
if( ti->up->trn ) {
PixelSetAlpha( pixels[x], (idx==0)?0:255 );
}
}
(void) PixelSyncIterator( iterator );
}
}
iterator = DestroyPixelIterator( iterator );
status = MagickWriteImage( image_wand, filename );
if( status == MagickFalse ) {
printf( "%s: file save error\n", filename );
}
image_wand = DestroyMagickWand( image_wand );
MagickWandTerminus();
} while( 0 );