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 );