Here is what the image looks like on ppc64:

Here is what it should look like:

And here is a link to the original PSD file: http://snisurset.net/tmp/abydos.psd
Code: Select all
convert abydos.psd[1-3] -background none -flatten result.png
Code: Select all
#include <cairo.h>
#include <fcntl.h>
#include <MagickCore/MagickCore.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define QUANTUM_MAX (0xffffffff>>(32-MAGICKCORE_QUANTUM_DEPTH))
static cairo_surface_t *
surface_from_image(Image *image,ExceptionInfo *exception)
{
cairo_surface_t *surface;
const Quantum *src;
int channels;
uint32_t *dst;
int rowskip;
int x;
int y;
src = GetVirtualPixels(image,0,0,image->columns,image->rows,exception);
if(exception->severity){
ClearMagickException(exception);
return NULL;
}
channels = GetPixelChannels(image);
if(GetImageAlphaChannel(image)){
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,image->columns,image->rows);
}else{
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,image->columns,image->rows);
}
dst = (uint32_t*)cairo_image_surface_get_data(surface);
rowskip = cairo_image_surface_get_stride(surface)/sizeof(uint32_t) - image->columns;;
for(y=0;y<image->rows;++y){
for(x=0;x<image->columns;++x){
int alpha = GetPixelAlpha(image,src);
int r = alpha*GetPixelRed(image,src)/QUANTUM_MAX;
int g = alpha*GetPixelGreen(image,src)/QUANTUM_MAX;
int b = alpha*GetPixelBlue(image,src)/QUANTUM_MAX;
*dst++ = (r>>(MAGICKCORE_QUANTUM_DEPTH-8))<<16|
(g>>(MAGICKCORE_QUANTUM_DEPTH-8))<< 8|
(b>>(MAGICKCORE_QUANTUM_DEPTH-8))<< 0|
(alpha>>(MAGICKCORE_QUANTUM_DEPTH-8))<<24;
src += channels;
}
dst += rowskip;
}
cairo_surface_mark_dirty(surface);
return surface;
}
static cairo_surface_t *
surface_from_data(const char *data,size_t len)
{
cairo_surface_t *surface = NULL;
ExceptionInfo *exception = AcquireExceptionInfo();
ImageInfo *info = CloneImageInfo(NULL);
Image *image = NULL;
strcpy(info->magick,"PSD");
image = BlobToImage(info,data,len,exception);
if(exception->severity)
goto out;
DestroyImageInfo(info);
surface = surface_from_image(GetImageFromList(image,0),exception);
out:
if(image)
DestroyImage(image);
if(exception)
DestroyExceptionInfo(exception);
return surface;
}
static cairo_surface_t *
surface_from_file(const char *filename)
{
cairo_surface_t *surface = NULL;
struct stat st;
int fd;
void *data;
if(stat(filename,&st)<0)
return NULL;
fd = open(filename,O_RDONLY);
if(fd<0)
return NULL;
data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0);
if(data != MAP_FAILED){
surface = surface_from_data(data, st.st_size);
munmap(data, st.st_size);
}
close(fd);
return surface;
}
int
main(int argc,char **argv)
{
cairo_surface_t *surface;
MagickCoreGenesis(NULL,0);
surface = surface_from_file("abydos.psd");
if(surface){
cairo_surface_write_to_png(surface, "result.png");
cairo_surface_destroy(surface);
}
MagickCoreTerminus();
return 0;
}