OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* pngshim.c */ | 3 /* pngshim.c */ |
4 /* */ | 4 /* */ |
5 /* PNG Bitmap glyph support. */ | 5 /* PNG Bitmap glyph support. */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2013 by Google, Inc. */ | 7 /* Copyright 2013, 2014 by Google, Inc. */ |
8 /* Written by Stuart Gill and Behdad Esfahbod. */ | 8 /* Written by Stuart Gill and Behdad Esfahbod. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used, */ | 10 /* This file is part of the FreeType project, and may only be used, */ |
11 /* modified, and distributed under the terms of the FreeType project */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
18 | 18 |
19 #include "../../include/ft2build.h" | 19 #include <ft2build.h> |
20 #include "../../include/freetype/internal/ftdebug.h" | 20 #include FT_INTERNAL_DEBUG_H |
21 #include "../../include/freetype/internal/ftstream.h" | 21 #include FT_INTERNAL_STREAM_H |
22 #include "../../include/freetype/tttags.h" | 22 #include FT_TRUETYPE_TAGS_H |
23 #include "../../include/freetype/config/ftstdlib.h" | 23 #include FT_CONFIG_STANDARD_LIBRARY_H |
24 | 24 |
25 | 25 |
26 #ifdef FT_CONFIG_OPTION_USE_PNG | 26 #ifdef FT_CONFIG_OPTION_USE_PNG |
27 | 27 |
28 /* We always include <stjmp.h>, so make libpng shut up! */ | 28 /* We always include <stjmp.h>, so make libpng shut up! */ |
29 #define PNG_SKIP_SETJMP_CHECK 1 | 29 #define PNG_SKIP_SETJMP_CHECK 1 |
30 #include <png.h> | 30 #include <png.h> |
31 #include "pngshim.h" | 31 #include "pngshim.h" |
32 | 32 |
33 #include "sferrors.h" | 33 #include "sferrors.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 base[3] = 0xFF; | 115 base[3] = 0xFF; |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 | 119 |
120 /* Use error callback to avoid png writing to stderr. */ | 120 /* Use error callback to avoid png writing to stderr. */ |
121 static void | 121 static void |
122 error_callback( png_structp png, | 122 error_callback( png_structp png, |
123 png_const_charp error_msg ) | 123 png_const_charp error_msg ) |
124 { | 124 { |
125 FT_Error* error = png_get_error_ptr( png ); | 125 FT_Error* error = (FT_Error*)png_get_error_ptr( png ); |
126 | 126 |
127 FT_UNUSED( error_msg ); | 127 FT_UNUSED( error_msg ); |
128 | 128 |
129 | 129 |
130 *error = FT_THROW( Out_Of_Memory ); | 130 *error = FT_THROW( Out_Of_Memory ); |
131 #ifdef PNG_SETJMP_SUPPORTED | 131 #ifdef PNG_SETJMP_SUPPORTED |
132 longjmp( png_jmpbuf( png ), 1 ); | 132 ft_longjmp( png_jmpbuf( png ), 1 ); |
133 #endif | 133 #endif |
134 /* if we get here, then we have no choice but to abort ... */ | 134 /* if we get here, then we have no choice but to abort ... */ |
135 } | 135 } |
136 | 136 |
137 | 137 |
138 /* Use warning callback to avoid png writing to stderr. */ | 138 /* Use warning callback to avoid png writing to stderr. */ |
139 static void | 139 static void |
140 warning_callback( png_structp png, | 140 warning_callback( png_structp png, |
141 png_const_charp error_msg ) | 141 png_const_charp error_msg ) |
142 { | 142 { |
143 FT_UNUSED( png ); | 143 FT_UNUSED( png ); |
144 FT_UNUSED( error_msg ); | 144 FT_UNUSED( error_msg ); |
145 | 145 |
146 /* Just ignore warnings. */ | 146 /* Just ignore warnings. */ |
147 } | 147 } |
148 | 148 |
149 | 149 |
150 static void | 150 static void |
151 read_data_from_FT_Stream( png_structp png, | 151 read_data_from_FT_Stream( png_structp png, |
152 png_bytep data, | 152 png_bytep data, |
153 png_size_t length ) | 153 png_size_t length ) |
154 { | 154 { |
155 FT_Error error; | 155 FT_Error error; |
156 png_voidp p = png_get_io_ptr( png ); | 156 png_voidp p = png_get_io_ptr( png ); |
157 FT_Stream stream = (FT_Stream)p; | 157 FT_Stream stream = (FT_Stream)p; |
158 | 158 |
159 | 159 |
160 if ( FT_FRAME_ENTER( length ) ) | 160 if ( FT_FRAME_ENTER( length ) ) |
161 { | 161 { |
162 FT_Error* e = png_get_error_ptr( png ); | 162 FT_Error* e = (FT_Error*)png_get_error_ptr( png ); |
163 | 163 |
164 | 164 |
165 *e = FT_THROW( Invalid_Stream_Read ); | 165 *e = FT_THROW( Invalid_Stream_Read ); |
166 png_error( png, NULL ); | 166 png_error( png, NULL ); |
167 | 167 |
168 return; | 168 return; |
169 } | 169 } |
170 | 170 |
171 memcpy( data, stream->cursor, length ); | 171 memcpy( data, stream->cursor, length ); |
172 | 172 |
173 FT_FRAME_EXIT(); | 173 FT_FRAME_EXIT(); |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 static FT_Error | 177 FT_LOCAL_DEF( FT_Error ) |
178 Load_SBit_Png( FT_Bitmap* map, | 178 Load_SBit_Png( FT_GlyphSlot slot, |
179 FT_Int x_offset, | 179 FT_Int x_offset, |
180 FT_Int y_offset, | 180 FT_Int y_offset, |
181 FT_Int pix_bits, | 181 FT_Int pix_bits, |
182 TT_SBit_Metrics metrics, | 182 TT_SBit_Metrics metrics, |
183 FT_Memory memory, | 183 FT_Memory memory, |
184 FT_Byte* data, | 184 FT_Byte* data, |
185 FT_UInt png_len ) | 185 FT_UInt png_len, |
| 186 FT_Bool populate_map_and_metrics ) |
186 { | 187 { |
| 188 FT_Bitmap *map = &slot->bitmap; |
187 FT_Error error = FT_Err_Ok; | 189 FT_Error error = FT_Err_Ok; |
188 FT_StreamRec stream; | 190 FT_StreamRec stream; |
189 | 191 |
190 png_structp png; | 192 png_structp png; |
191 png_infop info; | 193 png_infop info; |
192 png_uint_32 imgWidth, imgHeight; | 194 png_uint_32 imgWidth, imgHeight; |
193 | 195 |
194 int bitdepth, color_type, interlace; | 196 int bitdepth, color_type, interlace; |
195 FT_Int i; | 197 FT_Int i; |
196 png_byte* *rows; | 198 png_byte* *rows = NULL; /* pacify compiler */ |
197 | 199 |
198 | 200 |
199 if ( x_offset < 0 || x_offset + metrics->width > map->width || | 201 if ( x_offset < 0 || |
200 y_offset < 0 || y_offset + metrics->height > map->rows || | 202 y_offset < 0 ) |
201 pix_bits != 32 || map->pixel_mode != FT_PIXEL_MODE_BGRA ) | |
202 { | 203 { |
203 error = FT_THROW( Invalid_Argument ); | 204 error = FT_THROW( Invalid_Argument ); |
204 goto Exit; | 205 goto Exit; |
| 206 } |
| 207 |
| 208 if ( !populate_map_and_metrics && |
| 209 ( (FT_UInt)x_offset + metrics->width > map->width || |
| 210 (FT_UInt)y_offset + metrics->height > map->rows || |
| 211 pix_bits != 32 || |
| 212 map->pixel_mode != FT_PIXEL_MODE_BGRA ) ) |
| 213 { |
| 214 error = FT_THROW( Invalid_Argument ); |
| 215 goto Exit; |
205 } | 216 } |
206 | 217 |
207 FT_Stream_OpenMemory( &stream, data, png_len ); | 218 FT_Stream_OpenMemory( &stream, data, png_len ); |
208 | 219 |
209 png = png_create_read_struct( PNG_LIBPNG_VER_STRING, | 220 png = png_create_read_struct( PNG_LIBPNG_VER_STRING, |
210 &error, | 221 &error, |
211 error_callback, | 222 error_callback, |
212 warning_callback ); | 223 warning_callback ); |
213 if ( !png ) | 224 if ( !png ) |
214 { | 225 { |
(...skipping 16 matching lines...) Expand all Loading... |
231 } | 242 } |
232 | 243 |
233 png_set_read_fn( png, &stream, read_data_from_FT_Stream ); | 244 png_set_read_fn( png, &stream, read_data_from_FT_Stream ); |
234 | 245 |
235 png_read_info( png, info ); | 246 png_read_info( png, info ); |
236 png_get_IHDR( png, info, | 247 png_get_IHDR( png, info, |
237 &imgWidth, &imgHeight, | 248 &imgWidth, &imgHeight, |
238 &bitdepth, &color_type, &interlace, | 249 &bitdepth, &color_type, &interlace, |
239 NULL, NULL ); | 250 NULL, NULL ); |
240 | 251 |
241 if ( error != FT_Err_Ok || | 252 if ( error || |
242 (FT_Int)imgWidth != metrics->width || | 253 ( !populate_map_and_metrics && |
243 (FT_Int)imgHeight != metrics->height ) | 254 ( (FT_Int)imgWidth != metrics->width || |
| 255 (FT_Int)imgHeight != metrics->height ) ) ) |
244 goto DestroyExit; | 256 goto DestroyExit; |
245 | 257 |
| 258 if ( populate_map_and_metrics ) |
| 259 { |
| 260 FT_Long size; |
| 261 |
| 262 |
| 263 metrics->width = (FT_Int)imgWidth; |
| 264 metrics->height = (FT_Int)imgHeight; |
| 265 |
| 266 map->width = metrics->width; |
| 267 map->rows = metrics->height; |
| 268 map->pixel_mode = FT_PIXEL_MODE_BGRA; |
| 269 map->pitch = map->width * 4; |
| 270 map->num_grays = 256; |
| 271 |
| 272 /* reject too large bitmaps similarly to the rasterizer */ |
| 273 if ( map->rows > 0x7FFF || map->width > 0x7FFF ) |
| 274 { |
| 275 error = FT_THROW( Array_Too_Large ); |
| 276 goto DestroyExit; |
| 277 } |
| 278 |
| 279 /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ |
| 280 size = map->rows * map->pitch; |
| 281 |
| 282 error = ft_glyphslot_alloc_bitmap( slot, size ); |
| 283 if ( error ) |
| 284 goto DestroyExit; |
| 285 } |
| 286 |
246 /* convert palette/gray image to rgb */ | 287 /* convert palette/gray image to rgb */ |
247 if ( color_type == PNG_COLOR_TYPE_PALETTE ) | 288 if ( color_type == PNG_COLOR_TYPE_PALETTE ) |
248 png_set_palette_to_rgb( png ); | 289 png_set_palette_to_rgb( png ); |
249 | 290 |
250 /* expand gray bit depth if needed */ | 291 /* expand gray bit depth if needed */ |
251 if ( color_type == PNG_COLOR_TYPE_GRAY ) | 292 if ( color_type == PNG_COLOR_TYPE_GRAY ) |
252 { | 293 { |
253 #if PNG_LIBPNG_VER >= 10209 | 294 #if PNG_LIBPNG_VER >= 10209 |
254 png_set_expand_gray_1_2_4_to_8( png ); | 295 png_set_expand_gray_1_2_4_to_8( png ); |
255 #else | 296 #else |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 FT_Stream_Close( &stream ); | 368 FT_Stream_Close( &stream ); |
328 | 369 |
329 Exit: | 370 Exit: |
330 return error; | 371 return error; |
331 } | 372 } |
332 | 373 |
333 #endif /* FT_CONFIG_OPTION_USE_PNG */ | 374 #endif /* FT_CONFIG_OPTION_USE_PNG */ |
334 | 375 |
335 | 376 |
336 /* END */ | 377 /* END */ |
OLD | NEW |