mirror of
https://github.com/azure-rtos/guix.git
synced 2025-02-04 07:13:17 +08:00
841 lines
20 KiB
C++
841 lines
20 KiB
C++
|
|
#include "studiox_includes.h"
|
|
#include "image_reader.h"
|
|
#include "png.h"
|
|
|
|
png_structp png_instance;
|
|
png_infop png_info_ptr;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
input_stream::input_stream(unsigned char* data, int data_size)
|
|
{
|
|
mpData = data;
|
|
mDataSize = data_size;
|
|
mReadSize = 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
IFACEMETHODIMP input_stream::Read(void *pv, ULONG cb, ULONG *pcbRead)
|
|
{
|
|
if (mReadSize < mDataSize)
|
|
{
|
|
ULONG remain_size = mDataSize - mReadSize;
|
|
|
|
if (cb <= remain_size)
|
|
{
|
|
memcpy((void *)pv, (void *)(mpData + mReadSize), cb); /* Use case of memcpy is verified. */
|
|
mReadSize += cb;
|
|
|
|
if (pcbRead)
|
|
{
|
|
*pcbRead = cb;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memcpy((void *)pv, (void *)(mpData + mReadSize), remain_size); /* Use case of memcpy is verified. */
|
|
mReadSize += remain_size;
|
|
|
|
if (pcbRead)
|
|
{
|
|
*pcbRead = remain_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
png_reader::png_reader() : image_reader()
|
|
{
|
|
mpRowPointers = NULL;
|
|
}
|
|
|
|
png_reader::~png_reader()
|
|
{
|
|
}
|
|
|
|
BOOL png_reader::CheckImageHasAlphaChannel(CString &path)
|
|
{
|
|
BOOL has_alpha = FALSE;
|
|
UCHAR signature[8];
|
|
|
|
FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
|
|
|
|
if (!file)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
fread(signature, 1, 8, file);
|
|
if (png_sig_cmp(signature, 0, 8))
|
|
{
|
|
fclose(file);
|
|
return FALSE;
|
|
}
|
|
|
|
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
|
NULL, NULL, NULL);
|
|
|
|
if (!png_ptr)
|
|
{
|
|
fclose(file);
|
|
return FALSE;
|
|
}
|
|
|
|
png_infop info = png_create_info_struct(png_ptr);
|
|
|
|
if (!info)
|
|
{
|
|
fclose(file);
|
|
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
png_init_io(png_ptr, file);
|
|
png_set_sig_bytes(png_ptr, 8);
|
|
png_read_info(png_ptr, info);
|
|
|
|
int color_type, num_trans;
|
|
|
|
//get information from the info
|
|
if (png_get_IHDR(png_ptr, info, NULL, NULL, NULL, &color_type, NULL, NULL, NULL) == 0)
|
|
{
|
|
color_type = -1;
|
|
}
|
|
|
|
if (png_get_tRNS(png_ptr, info, NULL, &num_trans, NULL) == 0)
|
|
{
|
|
num_trans = 0;
|
|
}
|
|
|
|
switch (color_type)
|
|
{
|
|
case PNG_COLOR_TYPE_RGB_ALPHA:
|
|
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
|
has_alpha = TRUE;
|
|
break;
|
|
|
|
case PNG_COLOR_TYPE_PALETTE:
|
|
case PNG_COLOR_TYPE_GRAY:
|
|
case PNG_COLOR_TYPE_RGB:
|
|
|
|
if (num_trans > 0)
|
|
{
|
|
has_alpha = TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
png_destroy_read_struct(&png_ptr, &info, NULL);
|
|
fclose(file);
|
|
return has_alpha;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL png_reader::ReadImage(CString &path, int frame_id)
|
|
{
|
|
UCHAR signature[8];
|
|
|
|
FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
|
|
|
|
if (!file)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
fread(signature, 1, 8, file);
|
|
if (png_sig_cmp(signature, 0, 8))
|
|
{
|
|
fclose(file);
|
|
return FALSE;
|
|
}
|
|
|
|
m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
|
NULL, NULL, NULL);
|
|
|
|
if (!m_png)
|
|
{
|
|
fclose(file);
|
|
return FALSE;
|
|
}
|
|
png_instance = m_png;
|
|
|
|
m_info = png_create_info_struct(m_png);
|
|
if (!m_info)
|
|
{
|
|
fclose(file);
|
|
png_destroy_read_struct(&m_png, NULL, NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
png_init_io(m_png, file);
|
|
png_set_sig_bytes(m_png, 8);
|
|
png_read_png(m_png, m_info, PNG_TRANSFORM_IDENTITY, NULL);
|
|
png_info_ptr = m_info;
|
|
|
|
png_uint_32 width, height;
|
|
|
|
// get information from the m_info
|
|
if (png_get_IHDR(m_png, m_info, &width, &height, NULL, NULL, NULL, NULL, NULL) != 0)
|
|
{
|
|
mpRowPointers = png_get_rows(m_png, m_info);
|
|
|
|
if (mpRowPointers)
|
|
{
|
|
ConfigureInternalFormat();
|
|
DoCompress(FALSE);
|
|
if (!FinalizeImage(width, height))
|
|
{
|
|
png_destroy_read_struct(&m_png, &m_info, NULL);
|
|
fclose(file);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
png_destroy_read_struct(&m_png, &m_info, NULL);
|
|
fclose(file);
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL png_reader::ReadImage(IStream *input_stream)
|
|
{
|
|
UCHAR signature[8];
|
|
|
|
input_stream->Read(signature, 8, NULL);
|
|
|
|
if (png_sig_cmp(signature, 0, 8))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
|
NULL, NULL, NULL);
|
|
|
|
if (!m_png)
|
|
{
|
|
return FALSE;
|
|
}
|
|
png_instance = m_png;
|
|
|
|
m_info = png_create_info_struct(m_png);
|
|
if (!m_info)
|
|
{
|
|
png_destroy_read_struct(&m_png, NULL, NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
// Set user-defined function for reading a PNG stream.
|
|
png_set_read_fn(m_png, input_stream, ReadDataFromIStream);
|
|
|
|
png_set_sig_bytes(m_png, 8);
|
|
png_read_png(m_png, m_info, PNG_TRANSFORM_IDENTITY, NULL);
|
|
png_info_ptr = m_info;
|
|
|
|
png_uint_32 width, height;
|
|
|
|
// get information from the m_info
|
|
if (png_get_IHDR(m_png, m_info, &width, &height, NULL, NULL, NULL, NULL, NULL) != 0)
|
|
{
|
|
mpRowPointers = png_get_rows(m_png, m_info);
|
|
|
|
if (mpRowPointers)
|
|
{
|
|
ConfigureInternalFormat();
|
|
DoCompress(FALSE);
|
|
if (!FinalizeImage(width, height))
|
|
{
|
|
png_destroy_read_struct(&m_png, &m_info, NULL);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
png_destroy_read_struct(&m_png, &m_info, NULL);
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL png_reader::ReadImage(unsigned char* data, int data_size)
|
|
{
|
|
input_stream inputstream(data, data_size);
|
|
|
|
return ReadImage((IStream *)&inputstream);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
UCHAR *png_reader::GetInputDataPtr(int row)
|
|
{
|
|
if (mpRowPointers)
|
|
{
|
|
return mpRowPointers[row];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// the data formats supported by the PNG decoder are not always
|
|
// formats that our image_reader understands, so we have to convert
|
|
// the odd formats to something we do understand
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel48(image_reader *reader, int Index, Pixel *Pixel)
|
|
{
|
|
const USHORT *pGet = (USHORT *)reader->mpGetData;
|
|
pGet += Index * 3;
|
|
Pixel->Red = *pGet++;
|
|
Pixel->Green = *pGet++;
|
|
Pixel->Blue = *pGet;
|
|
|
|
int num_trans;
|
|
png_color_16p trans_color;
|
|
if (png_get_tRNS(png_instance, png_info_ptr, NULL, &num_trans, &trans_color) == 0)
|
|
{
|
|
num_trans = 0;
|
|
trans_color = NULL;
|
|
}
|
|
|
|
if ((num_trans > 0) &&
|
|
(trans_color->red == Pixel->Red) &&
|
|
(trans_color->green == Pixel->Green) &&
|
|
(trans_color->blue == Pixel->Blue))
|
|
{
|
|
//Transparent
|
|
Pixel->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
Pixel->Red &= 0xff;
|
|
Pixel->Green &= 0xff;
|
|
Pixel->Blue &= 0xff;
|
|
Pixel->Alpha = 0xff;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel1(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
UCHAR pal_index;
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
put->Red = put->Green = put->Blue = put->Alpha = 0;
|
|
|
|
pGet += (Index >> 3);
|
|
pal_index = *pGet;
|
|
pal_index >>= (7 - (Index & 0x07));
|
|
pal_index &= 0x01;
|
|
|
|
png_colorp palette;
|
|
int num_palette, num_trans;
|
|
png_bytep trans_alpha;
|
|
png_color_16p trans_color;
|
|
|
|
//get information from the png_ingo
|
|
|
|
if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
|
|
{
|
|
palette = NULL;
|
|
num_palette = 0;
|
|
}
|
|
|
|
if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
|
|
{
|
|
trans_alpha = NULL;
|
|
num_trans = 0;
|
|
trans_color = NULL;
|
|
}
|
|
|
|
|
|
if (palette)
|
|
{
|
|
//Palette
|
|
if ((num_trans > 0) && (trans_alpha[0] == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
if (pal_index < num_palette)
|
|
{
|
|
put->Red = palette[pal_index].red;
|
|
put->Green = palette[pal_index].green;
|
|
put->Blue = palette[pal_index].blue;
|
|
}
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Gray
|
|
if ((num_trans > 0) && (trans_color->gray == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
pal_index *= 255;
|
|
put->Red = pal_index;
|
|
put->Green = pal_index;
|
|
put->Blue = pal_index;
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel2(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
UCHAR pal_index;
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
put->Red = put->Green = put->Blue = put->Alpha = 0;
|
|
|
|
pGet += (Index >> 2);
|
|
pal_index = *pGet;
|
|
pal_index >>= (3 - (Index & 0x03)) * 2;
|
|
pal_index &= 0x03;
|
|
|
|
png_colorp palette;
|
|
int num_palette, num_trans;
|
|
png_bytep trans_alpha;
|
|
png_color_16p trans_color;
|
|
|
|
//get information from the png_info
|
|
if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
|
|
{
|
|
palette = NULL;
|
|
num_palette = 0;
|
|
}
|
|
|
|
if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
|
|
{
|
|
trans_alpha = NULL;
|
|
num_trans = 0;
|
|
trans_color = NULL;
|
|
}
|
|
|
|
if (palette)
|
|
{
|
|
//Palette
|
|
if ((num_trans > 0) && (trans_alpha[0] == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
if (pal_index < num_palette)
|
|
{
|
|
put->Red = palette[pal_index].red;
|
|
put->Green = palette[pal_index].green;
|
|
put->Blue = palette[pal_index].blue;
|
|
}
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Gray
|
|
if ((num_trans > 0) && (trans_color->gray == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
pal_index = pal_index * 255 / 3;
|
|
put->Red = pal_index;
|
|
put->Green = pal_index;
|
|
put->Blue = pal_index;
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel4(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
UCHAR pal_index;
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
put->Red = put->Green = put->Blue = put->Alpha = 0;
|
|
|
|
pGet += (Index >> 1);
|
|
pal_index = *pGet;
|
|
pal_index >>= (1 - (Index & 0x01)) * 4;
|
|
pal_index &= 0x0f;
|
|
|
|
png_colorp palette;
|
|
int num_palette, num_trans;
|
|
png_bytep trans_alpha;
|
|
png_color_16p trans_color;
|
|
|
|
// get information from the png_info
|
|
if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
|
|
{
|
|
palette = NULL;
|
|
num_palette = 0;
|
|
}
|
|
|
|
if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
|
|
{
|
|
trans_alpha = NULL;
|
|
num_trans = 0;
|
|
trans_color = NULL;
|
|
}
|
|
|
|
if (palette)
|
|
{
|
|
//Palette
|
|
if ((num_trans > 0) && (trans_alpha[0] == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
if (pal_index < num_palette)
|
|
{
|
|
put->Red = palette[pal_index].red;
|
|
put->Green = palette[pal_index].green;
|
|
put->Blue = palette[pal_index].blue;
|
|
}
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Gray
|
|
|
|
if ((num_trans > 0) && (trans_color->gray == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
pal_index = pal_index * 255 / 15;
|
|
put->Red = pal_index;
|
|
put->Green = pal_index;
|
|
put->Blue = pal_index;
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel8(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
UCHAR pal_index;
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
put->Red = put->Green = put->Blue = put->Alpha = 0;
|
|
|
|
pGet += Index;
|
|
pal_index = *pGet;
|
|
|
|
int color_type, num_palette, num_trans;
|
|
png_colorp palette;
|
|
png_bytep trans_alpha;
|
|
png_color_16p trans_color;
|
|
|
|
//get information from the info
|
|
if (png_get_IHDR(png_instance, png_info_ptr, NULL, NULL, NULL, &color_type, NULL, NULL, NULL) == 0)
|
|
{
|
|
color_type = -1;
|
|
}
|
|
|
|
|
|
if (png_get_PLTE(png_instance, png_info_ptr, &palette, &num_palette) == 0)
|
|
{
|
|
palette = NULL;
|
|
num_palette = 0;
|
|
}
|
|
|
|
if (png_get_tRNS(png_instance, png_info_ptr, &trans_alpha, &num_trans, &trans_color) == 0)
|
|
{
|
|
trans_alpha = NULL;
|
|
num_trans = 0;
|
|
trans_color = NULL;
|
|
}
|
|
|
|
switch(color_type)
|
|
{
|
|
case 3: // indexed color
|
|
if (pal_index < num_palette)
|
|
{
|
|
put->Red = palette[pal_index].red;
|
|
put->Green = palette[pal_index].green;
|
|
put->Blue = palette[pal_index].blue;
|
|
}
|
|
if (pal_index < num_trans)
|
|
{
|
|
put->Alpha = trans_alpha[pal_index];
|
|
}
|
|
else
|
|
{
|
|
put->Alpha = 0xff;
|
|
}
|
|
break;
|
|
|
|
case 2: // TrueColor image data
|
|
if (pal_index < num_palette)
|
|
{
|
|
put->Red = palette[pal_index].red;
|
|
put->Green = palette[pal_index].green;
|
|
put->Blue = palette[pal_index].blue;
|
|
}
|
|
if ((num_trans > 0) && (trans_alpha[0] == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
put->Alpha = 0xff;
|
|
}
|
|
break;
|
|
|
|
case 0: // grayscale
|
|
//Gray
|
|
if ((num_trans > 0) && (trans_color->gray == pal_index))
|
|
{
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
put->Red = pal_index;
|
|
put->Green = pal_index;
|
|
put->Blue = pal_index;
|
|
put->Alpha = 0xff;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel24(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
pGet += Index * 3;
|
|
|
|
put->Red = *pGet++;
|
|
put->Green = *pGet++;
|
|
put->Blue = *pGet++;
|
|
|
|
int num_trans;
|
|
png_color_16p trans_color;
|
|
|
|
if (png_get_tRNS(png_instance, png_info_ptr, NULL, &num_trans, &trans_color) == 0)
|
|
{
|
|
trans_color = NULL;
|
|
num_trans = 0;
|
|
}
|
|
|
|
if ((num_trans > 0) &&
|
|
(trans_color->red == put->Red) &&
|
|
(trans_color->green == put->Green) &&
|
|
(trans_color->blue == put->Blue))
|
|
{
|
|
//Transparent
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel64(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
pGet += Index * 8;
|
|
put->Red = *pGet;
|
|
pGet += 2;
|
|
put->Green = *pGet;
|
|
pGet += 2;
|
|
put->Blue = *pGet;
|
|
pGet += 2;
|
|
put->Alpha = *pGet;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel24Alpha(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
pGet += Index * 4;
|
|
put->Red = *pGet++;
|
|
put->Green = *pGet++;
|
|
put->Blue = *pGet++;
|
|
put->Alpha = *pGet;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel8Alpha(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
pGet += Index * 2;
|
|
put->Red = put->Green = put->Blue = *pGet++;
|
|
put->Alpha = *pGet;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel16To8(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
const USHORT *pGet = (USHORT *)reader->mpGetData;
|
|
int gray;
|
|
|
|
pGet += Index;
|
|
gray = *pGet;
|
|
|
|
int num_trans;
|
|
png_color_16p trans_color;
|
|
|
|
if (png_get_tRNS(png_instance, png_info_ptr, NULL, &num_trans, &trans_color) == 0)
|
|
{
|
|
num_trans = 0;
|
|
trans_color = NULL;
|
|
}
|
|
|
|
if ((num_trans > 0) && (trans_color->gray == gray))
|
|
{
|
|
//Transparent
|
|
put->Alpha = 0;
|
|
}
|
|
else
|
|
{
|
|
put->Red = put->Green = put->Blue = (GX_UBYTE)gray;
|
|
put->Alpha = 0xff;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadPixel16Alpha(image_reader *reader, int Index, Pixel *put)
|
|
{
|
|
const GX_UBYTE *pGet = reader->mpGetData;
|
|
|
|
pGet += (Index * 4);
|
|
put->Red = put->Green = put->Blue = *pGet;
|
|
pGet += 2;
|
|
put->Alpha = *pGet;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ReadDataFromIStream(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead)
|
|
{
|
|
IStream *inputstream = (IStream *)png_get_io_ptr(png_ptr);
|
|
|
|
if (inputstream)
|
|
{
|
|
inputstream->Read(outBytes, byteCountToRead, GX_NULL);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void png_reader::ConfigureInternalFormat()
|
|
{
|
|
mInputHasAlpha = FALSE;
|
|
|
|
int bit_depth, color_type, num_trans;
|
|
|
|
//get information from the info
|
|
if (png_get_IHDR(m_png, m_info, NULL, NULL, &bit_depth, &color_type, NULL, NULL, NULL) == 0)
|
|
{
|
|
bit_depth = 0;
|
|
color_type = -1;
|
|
}
|
|
|
|
if (png_get_tRNS(m_png, m_info, NULL, &num_trans, NULL) == 0)
|
|
{
|
|
num_trans = 0;
|
|
}
|
|
|
|
switch(color_type)
|
|
{
|
|
case PNG_COLOR_TYPE_RGB:
|
|
if (num_trans > 0)
|
|
{
|
|
mInputHasAlpha = TRUE;
|
|
}
|
|
|
|
if (bit_depth == 8)
|
|
{
|
|
// use standard raw reader provided by base class
|
|
//SetDefaultPixelReader(24);
|
|
mpReadInputPixel = &png_reader::ReadPixel24;
|
|
}
|
|
else
|
|
{
|
|
// the input file has 16-bit channels. Use
|
|
// my own reader
|
|
mpReadInputPixel = &png_reader::ReadPixel48;
|
|
}
|
|
break;
|
|
|
|
case PNG_COLOR_TYPE_RGB_ALPHA:
|
|
mInputHasAlpha = TRUE;
|
|
if (bit_depth == 8)
|
|
{
|
|
mpReadInputPixel = &png_reader::ReadPixel24Alpha;
|
|
}
|
|
else
|
|
{
|
|
// the input file has 16-bit color channels
|
|
mpReadInputPixel = &png_reader::ReadPixel64;
|
|
}
|
|
break;
|
|
|
|
case PNG_COLOR_TYPE_PALETTE:
|
|
case PNG_COLOR_TYPE_GRAY:
|
|
|
|
if (num_trans > 0)
|
|
{
|
|
mInputHasAlpha = TRUE;
|
|
}
|
|
|
|
switch(bit_depth)
|
|
{
|
|
case 1:
|
|
mpReadInputPixel = &png_reader::ReadPixel1;
|
|
break;
|
|
|
|
case 2:
|
|
mpReadInputPixel = &png_reader::ReadPixel2;
|
|
break;
|
|
|
|
case 4:
|
|
mpReadInputPixel = &png_reader::ReadPixel4;
|
|
break;
|
|
|
|
case 8:
|
|
mpReadInputPixel = &png_reader::ReadPixel8;
|
|
break;
|
|
|
|
case 16:
|
|
mpReadInputPixel = &png_reader::ReadPixel16To8;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
|
mInputHasAlpha = TRUE;
|
|
|
|
if (bit_depth == 8)
|
|
{
|
|
mpReadInputPixel = &png_reader::ReadPixel8Alpha;
|
|
}
|
|
else
|
|
{
|
|
mpReadInputPixel = &png_reader::ReadPixel16Alpha;
|
|
}
|
|
break;
|
|
}
|
|
}
|