1727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/***************************************************************************/ 2727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* */ 3727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* pngshim.c */ 4727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* */ 5727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* PNG Bitmap glyph support. */ 6727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* */ 79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/* Copyright 2013, 2014 by Google, Inc. */ 8727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* Written by Stuart Gill and Behdad Esfahbod. */ 9727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* */ 10727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* This file is part of the FreeType project, and may only be used, */ 11727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* modified, and distributed under the terms of the FreeType project */ 12727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* this file you indicate that you have read the license and */ 14727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* understand and accept it fully. */ 15727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* */ 16727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/***************************************************************************/ 17727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 18727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 19727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include <ft2build.h> 20727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_DEBUG_H 21727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_STREAM_H 22727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_TRUETYPE_TAGS_H 23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_CONFIG_STANDARD_LIBRARY_H 24727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 25727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_CONFIG_OPTION_USE_PNG 27727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 28727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* We always include <stjmp.h>, so make libpng shut up! */ 29727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define PNG_SKIP_SETJMP_CHECK 1 30727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include <png.h> 31727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "pngshim.h" 32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 33727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "sferrors.h" 34727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 35727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 36727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* This code is freely based on cairo-png.c. There's so many ways */ 37727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* to call libpng, and the way cairo does it is defacto standard. */ 38727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 39727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static int 40727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease multiply_alpha( int alpha, 41727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int color ) 42727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 43727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int temp = ( alpha * color ) + 0x80; 44727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 45727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 46727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return ( temp + ( temp >> 8 ) ) >> 8; 47727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 48727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 50727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Premultiplies data and converts RGBA bytes => native endian. */ 51727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static void 52727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease premultiply_data( png_structp png, 53727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_row_infop row_info, 54727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_bytep data ) 55727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 56727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int i; 57727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 58727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UNUSED( png ); 59727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 60727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 61727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( i = 0; i < row_info->rowbytes; i += 4 ) 62727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned char* base = &data[i]; 64727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int alpha = base[3]; 65727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 66727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 67727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( alpha == 0 ) 68727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[0] = base[1] = base[2] = base[3] = 0; 69727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 70727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 71727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 72727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int red = base[0]; 73727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int green = base[1]; 74727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int blue = base[2]; 75727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 76727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 77727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( alpha != 0xFF ) 78727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 79727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease red = multiply_alpha( alpha, red ); 80727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease green = multiply_alpha( alpha, green ); 81727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease blue = multiply_alpha( alpha, blue ); 82727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 83727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 84727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[0] = blue; 85727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[1] = green; 86727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[2] = red; 87727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[3] = alpha; 88727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 89727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 90727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 91727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 92727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 93727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Converts RGBx bytes to BGRA. */ 94727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static void 95727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease convert_bytes_to_data( png_structp png, 96727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_row_infop row_info, 97727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_bytep data ) 98727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 99727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int i; 100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UNUSED( png ); 102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( i = 0; i < row_info->rowbytes; i += 4 ) 105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned char* base = &data[i]; 107727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int red = base[0]; 108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int green = base[1]; 109727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease unsigned int blue = base[2]; 110727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 112727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[0] = blue; 113727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[1] = green; 114727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[2] = red; 115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease base[3] = 0xFF; 116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 118727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 119727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 120727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Use error callback to avoid png writing to stderr. */ 121727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static void 122727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error_callback( png_structp png, 123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_const_charp error_msg ) 124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 125ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Error* error = (FT_Error*)png_get_error_ptr( png ); 126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 127727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UNUSED( error_msg ); 128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *error = FT_THROW( Out_Of_Memory ); 131727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef PNG_SETJMP_SUPPORTED 1329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod ft_longjmp( png_jmpbuf( png ), 1 ); 133727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif 134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* if we get here, then we have no choice but to abort ... */ 135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 137727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 138727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Use warning callback to avoid png writing to stderr. */ 139727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static void 140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease warning_callback( png_structp png, 141727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_const_charp error_msg ) 142727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 143727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UNUSED( png ); 144727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UNUSED( error_msg ); 145727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Just ignore warnings. */ 147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 149727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 150727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease static void 151727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease read_data_from_FT_Stream( png_structp png, 152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_bytep data, 153727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_size_t length ) 154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error; 156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_voidp p = png_get_io_ptr( png ); 157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream stream = (FT_Stream)p; 158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( FT_FRAME_ENTER( length ) ) 161727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 162ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Error* e = (FT_Error*)png_get_error_ptr( png ); 163727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 165727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease *e = FT_THROW( Invalid_Stream_Read ); 166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_error( png, NULL ); 167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return; 169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 170727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 171727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease memcpy( data, stream->cursor, length ); 172727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 173727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FRAME_EXIT(); 174727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 176727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 177ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_LOCAL_DEF( FT_Error ) 178ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease Load_SBit_Png( FT_GlyphSlot slot, 179727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int x_offset, 180727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int y_offset, 181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int pix_bits, 182727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_SBit_Metrics metrics, 183727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Memory memory, 184727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* data, 185ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt png_len, 186ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bool populate_map_and_metrics ) 187727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 188ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Bitmap *map = &slot->bitmap; 189727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 190727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_StreamRec stream; 191727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 192727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_structp png; 193727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_infop info; 194727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_uint_32 imgWidth, imgHeight; 195727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 196727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int bitdepth, color_type, interlace; 197727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int i; 198ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease png_byte* *rows = NULL; /* pacify compiler */ 199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 200727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 201ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( x_offset < 0 || 202ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease y_offset < 0 ) 203ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 204ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = FT_THROW( Invalid_Argument ); 205ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto Exit; 206ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 207ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 208ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( !populate_map_and_metrics && 209ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( x_offset + metrics->width > map->width || 210ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease y_offset + metrics->height > map->rows || 211ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease pix_bits != 32 || 212ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pixel_mode != FT_PIXEL_MODE_BGRA ) ) 213727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_Argument ); 215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 217727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream_OpenMemory( &stream, data, png_len ); 219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 220727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 221727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease &error, 222727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error_callback, 223727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease warning_callback ); 224727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !png ) 225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 227727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 228727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 229727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 230727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease info = png_create_info_struct( png ); 231727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( !info ) 232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_destroy_read_struct( &png, NULL, NULL ); 235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto Exit; 236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 238727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( ft_setjmp( png_jmpbuf( png ) ) ) 239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 241727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto DestroyExit; 242727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 244727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_read_fn( png, &stream, read_data_from_FT_Stream ); 245727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 246727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_read_info( png, info ); 247727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_get_IHDR( png, info, 248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease &imgWidth, &imgHeight, 249727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease &bitdepth, &color_type, &interlace, 250727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease NULL, NULL ); 251727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 252ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error || 253ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( !populate_map_and_metrics && 254ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease ( (FT_Int)imgWidth != metrics->width || 255ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease (FT_Int)imgHeight != metrics->height ) ) ) 256727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto DestroyExit; 257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 258ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( populate_map_and_metrics ) 259ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease { 260ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Long size; 261ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 262ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 263ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->width = (FT_Int)imgWidth; 264ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease metrics->height = (FT_Int)imgHeight; 265ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 266ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->width = metrics->width; 267ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->rows = metrics->height; 268ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pixel_mode = FT_PIXEL_MODE_BGRA; 269ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->pitch = map->width * 4; 270ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease map->num_grays = 256; 271ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 272ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease size = map->rows * map->pitch; 273ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 274ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease error = ft_glyphslot_alloc_bitmap( slot, size ); 275ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease if ( error ) 276ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease goto DestroyExit; 277ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease } 278ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 279727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* convert palette/gray image to rgb */ 280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( color_type == PNG_COLOR_TYPE_PALETTE ) 281727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_palette_to_rgb( png ); 282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 283727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* expand gray bit depth if needed */ 284727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( color_type == PNG_COLOR_TYPE_GRAY ) 285727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 286727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#if PNG_LIBPNG_VER >= 10209 287727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_expand_gray_1_2_4_to_8( png ); 288727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#else 289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_gray_1_2_4_to_8( png ); 290727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif 291727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 292727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 293727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* transform transparency to alpha */ 294727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( png_get_valid(png, info, PNG_INFO_tRNS ) ) 295727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_tRNS_to_alpha( png ); 296727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 297727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( bitdepth == 16 ) 298727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_strip_16( png ); 299727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 300727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( bitdepth < 8 ) 301727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_packing( png ); 302727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* convert grayscale to RGB */ 304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( color_type == PNG_COLOR_TYPE_GRAY || 305727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) 306727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_gray_to_rgb( png ); 307727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( interlace != PNG_INTERLACE_NONE ) 309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_interlace_handling( png ); 310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_filler( png, 0xFF, PNG_FILLER_AFTER ); 312727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* recheck header after setting EXPAND options */ 314727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_read_update_info(png, info ); 315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_get_IHDR( png, info, 316727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease &imgWidth, &imgHeight, 317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease &bitdepth, &color_type, &interlace, 318727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease NULL, NULL ); 319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 320727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( bitdepth != 8 || 321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease !( color_type == PNG_COLOR_TYPE_RGB || 322727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease color_type == PNG_COLOR_TYPE_RGB_ALPHA ) ) 323727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 324727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Invalid_File_Format ); 325727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto DestroyExit; 326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 327727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 328727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease switch ( color_type ) 329727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 330727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease default: 331727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Shouldn't happen, but fall through. */ 332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case PNG_COLOR_TYPE_RGB_ALPHA: 334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_read_user_transform_fn( png, premultiply_data ); 335727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 336727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 337727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease case PNG_COLOR_TYPE_RGB: 338727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Humm, this smells. Carry on though. */ 339727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_set_read_user_transform_fn( png, convert_bytes_to_data ); 340727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease break; 341727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( FT_NEW_ARRAY( rows, imgHeight ) ) 344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease error = FT_THROW( Out_Of_Memory ); 346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease goto DestroyExit; 347727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 348727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 349727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( i = 0; i < (FT_Int)imgHeight; i++ ) 350727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4; 351727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 352727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_read_image( png, rows ); 353727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 354727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_FREE( rows ); 355727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 356727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_read_end( png, info ); 357727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 358727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease DestroyExit: 359727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease png_destroy_read_struct( &png, &info, NULL ); 360727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Stream_Close( &stream ); 361727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 362727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease Exit: 363727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return error; 364727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 366727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_CONFIG_OPTION_USE_PNG */ 367727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 368727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 369727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* END */ 370