mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-24 23:00:09 +01:00
144 lines
4 KiB
C++
144 lines
4 KiB
C++
/*
|
|
RGBAImage.cpp
|
|
Copyright (C) 2006 Yangli Hector Yee
|
|
|
|
This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
GNU General Public License as published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with this program;
|
|
if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "RGBAImage.h"
|
|
#include "png.h"
|
|
|
|
#if HAVE_LIBTIFF
|
|
#include "tiff.h"
|
|
#include "tiffio.h"
|
|
|
|
/* Reads Tiff Images */
|
|
RGBAImage* RGBAImage::ReadTiff(char *filename)
|
|
{
|
|
RGBAImage *fimg = 0;
|
|
|
|
TIFF* tif = TIFFOpen(filename, "r");
|
|
char emsg[1024];
|
|
emsg[0] = 0;
|
|
if (tif) {
|
|
TIFFRGBAImage img;
|
|
|
|
if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
|
|
size_t npixels;
|
|
uint32* raster;
|
|
|
|
npixels = img.width * img.height;
|
|
raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
|
|
if (raster != NULL) {
|
|
if (TIFFRGBAImageGet(&img, raster, img.width, img.height)) {
|
|
/* result is in ABGR */
|
|
fimg = new RGBAImage(img.width, img.height);
|
|
for (int y = img.height - 1; y >= 0; y--) {
|
|
for (int x = 0; x < (int) img.width; x++) {
|
|
fimg->Set(x,img.height - (y+1), raster[x + y * img.width]);
|
|
}
|
|
}
|
|
}
|
|
_TIFFfree(raster);
|
|
}
|
|
}
|
|
TIFFRGBAImageEnd(&img);
|
|
}
|
|
return fimg;
|
|
}
|
|
#endif /* HAVE_LIBTIFF */
|
|
|
|
/* This portion was written by Scott Corley */
|
|
RGBAImage* RGBAImage::ReadPNG(char *filename)
|
|
{
|
|
RGBAImage *fimg = 0;
|
|
FILE *fp=fopen(filename, "rb");
|
|
if (!fp)
|
|
{
|
|
return NULL;
|
|
}
|
|
png_byte header[8];
|
|
|
|
fread(header, 1, 8, fp);
|
|
bool is_png = !png_sig_cmp(header, 0, 8);
|
|
if (!is_png)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
png_structp png_ptr = png_create_read_struct
|
|
(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
|
|
NULL, NULL);
|
|
if (!png_ptr)
|
|
return (NULL);
|
|
|
|
png_infop info_ptr = png_create_info_struct(png_ptr);
|
|
if (!info_ptr)
|
|
{
|
|
png_destroy_read_struct(&png_ptr,
|
|
(png_infopp)NULL, (png_infopp)NULL);
|
|
return (NULL);
|
|
}
|
|
|
|
png_infop end_info = png_create_info_struct(png_ptr);
|
|
if (!end_info)
|
|
{
|
|
png_destroy_read_struct(&png_ptr, &info_ptr,
|
|
(png_infopp)NULL);
|
|
return (NULL);
|
|
}
|
|
|
|
png_init_io(png_ptr, fp);
|
|
png_set_sig_bytes(png_ptr, 8);
|
|
|
|
png_read_png(png_ptr, info_ptr, 0, NULL);
|
|
|
|
png_bytep *row_pointers;
|
|
row_pointers = png_get_rows(png_ptr, info_ptr);
|
|
|
|
fimg = new RGBAImage(png_ptr->width, png_ptr->height);
|
|
for (int y = 0; y < (int) png_ptr->height; y++) {
|
|
for (int x = 0; x < (int) png_ptr->width; x++) {
|
|
uint32_t value = 0;
|
|
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
value = ((uint32_t)row_pointers[y][x*4]) | (((uint32_t)row_pointers[y][x*4+1])<<8) | (((uint32_t)row_pointers[y][x*4+2])<<16) |(((uint32_t)row_pointers[y][x*4+3])<<24);
|
|
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
|
|
value = ((uint32_t)row_pointers[y][x*3] /*B*/) | (((uint32_t)row_pointers[y][x*3+1] /*G*/)<<8) | (((uint32_t)row_pointers[y][x*3+2]/*R*/)<<16) | (0xFFUL << 24);
|
|
fimg->Set(x,y, value);
|
|
}
|
|
}
|
|
|
|
png_read_destroy(png_ptr, info_ptr, end_info);
|
|
return fimg;
|
|
}
|
|
|
|
bool RGBAImage::WritePPM()
|
|
{
|
|
if (Width <= 0) return false;
|
|
if (Height <=0 ) return false;
|
|
FILE *out = fopen(Name.c_str(), "wb");
|
|
if (!out) return false;
|
|
fprintf(out, "P6\n%d %d 255\n", Width, Height);
|
|
for (int y = 0; y < Height; y++) {
|
|
for (int x = 0; x < Width; x++) {
|
|
int i = x + y * Width;
|
|
unsigned char r = Get_Red(i);
|
|
unsigned char g = Get_Green(i);
|
|
unsigned char b = Get_Blue(i);
|
|
fwrite(&r, 1, 1, out);
|
|
fwrite(&g, 1, 1, out);
|
|
fwrite(&b, 1, 1, out);
|
|
}
|
|
}
|
|
fclose(out);
|
|
return true;
|
|
}
|