Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / thirdparty / freetype-2.3.12 / src / base / ftstream.c
blobb638599dbcf7bfab6d51d36991128b6dcdb4bb41
1 /***************************************************************************/
2 /* */
3 /* ftstream.c */
4 /* */
5 /* I/O stream support (body). */
6 /* */
7 /* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
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 */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
19 #include <ft2build.h>
20 #include FT_INTERNAL_STREAM_H
21 #include FT_INTERNAL_DEBUG_H
24 /*************************************************************************/
25 /* */
26 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
27 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
28 /* messages during execution. */
29 /* */
30 #undef FT_COMPONENT
31 #define FT_COMPONENT trace_stream
34 FT_BASE_DEF( void )
35 FT_Stream_OpenMemory( FT_Stream stream,
36 const FT_Byte* base,
37 FT_ULong size )
39 stream->base = (FT_Byte*) base;
40 stream->size = size;
41 stream->pos = 0;
42 stream->cursor = 0;
43 stream->read = 0;
44 stream->close = 0;
48 FT_BASE_DEF( void )
49 FT_Stream_Close( FT_Stream stream )
51 if ( stream && stream->close )
52 stream->close( stream );
56 FT_BASE_DEF( FT_Error )
57 FT_Stream_Seek( FT_Stream stream,
58 FT_ULong pos )
60 FT_Error error = FT_Err_Ok;
63 if ( stream->read )
65 if ( stream->read( stream, pos, 0, 0 ) )
67 FT_ERROR(( "FT_Stream_Seek:"
68 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
69 pos, stream->size ));
71 error = FT_Err_Invalid_Stream_Operation;
74 /* note that seeking to the first position after the file is valid */
75 else if ( pos > stream->size )
77 FT_ERROR(( "FT_Stream_Seek:"
78 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
79 pos, stream->size ));
81 error = FT_Err_Invalid_Stream_Operation;
84 if ( !error )
85 stream->pos = pos;
87 return error;
91 FT_BASE_DEF( FT_Error )
92 FT_Stream_Skip( FT_Stream stream,
93 FT_Long distance )
95 if ( distance < 0 )
96 return FT_Err_Invalid_Stream_Operation;
98 return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );
102 FT_BASE_DEF( FT_Long )
103 FT_Stream_Pos( FT_Stream stream )
105 return stream->pos;
109 FT_BASE_DEF( FT_Error )
110 FT_Stream_Read( FT_Stream stream,
111 FT_Byte* buffer,
112 FT_ULong count )
114 return FT_Stream_ReadAt( stream, stream->pos, buffer, count );
118 FT_BASE_DEF( FT_Error )
119 FT_Stream_ReadAt( FT_Stream stream,
120 FT_ULong pos,
121 FT_Byte* buffer,
122 FT_ULong count )
124 FT_Error error = FT_Err_Ok;
125 FT_ULong read_bytes;
128 if ( pos >= stream->size )
130 FT_ERROR(( "FT_Stream_ReadAt:"
131 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
132 pos, stream->size ));
134 return FT_Err_Invalid_Stream_Operation;
137 if ( stream->read )
138 read_bytes = stream->read( stream, pos, buffer, count );
139 else
141 read_bytes = stream->size - pos;
142 if ( read_bytes > count )
143 read_bytes = count;
145 FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
148 stream->pos = pos + read_bytes;
150 if ( read_bytes < count )
152 FT_ERROR(( "FT_Stream_ReadAt:"
153 " invalid read; expected %lu bytes, got %lu\n",
154 count, read_bytes ));
156 error = FT_Err_Invalid_Stream_Operation;
159 return error;
163 FT_BASE_DEF( FT_ULong )
164 FT_Stream_TryRead( FT_Stream stream,
165 FT_Byte* buffer,
166 FT_ULong count )
168 FT_ULong read_bytes = 0;
171 if ( stream->pos >= stream->size )
172 goto Exit;
174 if ( stream->read )
175 read_bytes = stream->read( stream, stream->pos, buffer, count );
176 else
178 read_bytes = stream->size - stream->pos;
179 if ( read_bytes > count )
180 read_bytes = count;
182 FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
185 stream->pos += read_bytes;
187 Exit:
188 return read_bytes;
192 FT_BASE_DEF( FT_Error )
193 FT_Stream_ExtractFrame( FT_Stream stream,
194 FT_ULong count,
195 FT_Byte** pbytes )
197 FT_Error error;
200 error = FT_Stream_EnterFrame( stream, count );
201 if ( !error )
203 *pbytes = (FT_Byte*)stream->cursor;
205 /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
206 stream->cursor = 0;
207 stream->limit = 0;
210 return error;
214 FT_BASE_DEF( void )
215 FT_Stream_ReleaseFrame( FT_Stream stream,
216 FT_Byte** pbytes )
218 if ( stream && stream->read )
220 FT_Memory memory = stream->memory;
222 #ifdef FT_DEBUG_MEMORY
223 ft_mem_free( memory, *pbytes );
224 *pbytes = NULL;
225 #else
226 FT_FREE( *pbytes );
227 #endif
229 *pbytes = 0;
233 FT_BASE_DEF( FT_Error )
234 FT_Stream_EnterFrame( FT_Stream stream,
235 FT_ULong count )
237 FT_Error error = FT_Err_Ok;
238 FT_ULong read_bytes;
241 /* check for nested frame access */
242 FT_ASSERT( stream && stream->cursor == 0 );
244 if ( stream->read )
246 /* allocate the frame in memory */
247 FT_Memory memory = stream->memory;
249 #ifdef FT_DEBUG_MEMORY
250 /* assume _ft_debug_file and _ft_debug_lineno are already set */
251 stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
252 if ( error )
253 goto Exit;
254 #else
255 if ( FT_QALLOC( stream->base, count ) )
256 goto Exit;
257 #endif
258 /* read it */
259 read_bytes = stream->read( stream, stream->pos,
260 stream->base, count );
261 if ( read_bytes < count )
263 FT_ERROR(( "FT_Stream_EnterFrame:"
264 " invalid read; expected %lu bytes, got %lu\n",
265 count, read_bytes ));
267 FT_FREE( stream->base );
268 error = FT_Err_Invalid_Stream_Operation;
270 stream->cursor = stream->base;
271 stream->limit = stream->cursor + count;
272 stream->pos += read_bytes;
274 else
276 /* check current and new position */
277 if ( stream->pos >= stream->size ||
278 stream->pos + count > stream->size )
280 FT_ERROR(( "FT_Stream_EnterFrame:"
281 " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
282 stream->pos, count, stream->size ));
284 error = FT_Err_Invalid_Stream_Operation;
285 goto Exit;
288 /* set cursor */
289 stream->cursor = stream->base + stream->pos;
290 stream->limit = stream->cursor + count;
291 stream->pos += count;
294 Exit:
295 return error;
299 FT_BASE_DEF( void )
300 FT_Stream_ExitFrame( FT_Stream stream )
302 /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */
303 /* that it is possible to access a frame of length 0 in */
304 /* some weird fonts (usually, when accessing an array of */
305 /* 0 records, like in some strange kern tables). */
306 /* */
307 /* In this case, the loader code handles the 0-length table */
308 /* gracefully; however, stream.cursor is really set to 0 by the */
309 /* FT_Stream_EnterFrame() call, and this is not an error. */
310 /* */
311 FT_ASSERT( stream );
313 if ( stream->read )
315 FT_Memory memory = stream->memory;
317 #ifdef FT_DEBUG_MEMORY
318 ft_mem_free( memory, stream->base );
319 stream->base = NULL;
320 #else
321 FT_FREE( stream->base );
322 #endif
324 stream->cursor = 0;
325 stream->limit = 0;
329 FT_BASE_DEF( FT_Char )
330 FT_Stream_GetChar( FT_Stream stream )
332 FT_Char result;
335 FT_ASSERT( stream && stream->cursor );
337 result = 0;
338 if ( stream->cursor < stream->limit )
339 result = *stream->cursor++;
341 return result;
345 FT_BASE_DEF( FT_Short )
346 FT_Stream_GetShort( FT_Stream stream )
348 FT_Byte* p;
349 FT_Short result;
352 FT_ASSERT( stream && stream->cursor );
354 result = 0;
355 p = stream->cursor;
356 if ( p + 1 < stream->limit )
357 result = FT_NEXT_SHORT( p );
358 stream->cursor = p;
360 return result;
364 FT_BASE_DEF( FT_Short )
365 FT_Stream_GetShortLE( FT_Stream stream )
367 FT_Byte* p;
368 FT_Short result;
371 FT_ASSERT( stream && stream->cursor );
373 result = 0;
374 p = stream->cursor;
375 if ( p + 1 < stream->limit )
376 result = FT_NEXT_SHORT_LE( p );
377 stream->cursor = p;
379 return result;
383 FT_BASE_DEF( FT_Long )
384 FT_Stream_GetOffset( FT_Stream stream )
386 FT_Byte* p;
387 FT_Long result;
390 FT_ASSERT( stream && stream->cursor );
392 result = 0;
393 p = stream->cursor;
394 if ( p + 2 < stream->limit )
395 result = FT_NEXT_OFF3( p );
396 stream->cursor = p;
397 return result;
401 FT_BASE_DEF( FT_Long )
402 FT_Stream_GetLong( FT_Stream stream )
404 FT_Byte* p;
405 FT_Long result;
408 FT_ASSERT( stream && stream->cursor );
410 result = 0;
411 p = stream->cursor;
412 if ( p + 3 < stream->limit )
413 result = FT_NEXT_LONG( p );
414 stream->cursor = p;
415 return result;
419 FT_BASE_DEF( FT_Long )
420 FT_Stream_GetLongLE( FT_Stream stream )
422 FT_Byte* p;
423 FT_Long result;
426 FT_ASSERT( stream && stream->cursor );
428 result = 0;
429 p = stream->cursor;
430 if ( p + 3 < stream->limit )
431 result = FT_NEXT_LONG_LE( p );
432 stream->cursor = p;
433 return result;
437 FT_BASE_DEF( FT_Char )
438 FT_Stream_ReadChar( FT_Stream stream,
439 FT_Error* error )
441 FT_Byte result = 0;
444 FT_ASSERT( stream );
446 *error = FT_Err_Ok;
448 if ( stream->read )
450 if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
451 goto Fail;
453 else
455 if ( stream->pos < stream->size )
456 result = stream->base[stream->pos];
457 else
458 goto Fail;
460 stream->pos++;
462 return result;
464 Fail:
465 *error = FT_Err_Invalid_Stream_Operation;
466 FT_ERROR(( "FT_Stream_ReadChar:"
467 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
468 stream->pos, stream->size ));
470 return 0;
474 FT_BASE_DEF( FT_Short )
475 FT_Stream_ReadShort( FT_Stream stream,
476 FT_Error* error )
478 FT_Byte reads[2];
479 FT_Byte* p = 0;
480 FT_Short result = 0;
483 FT_ASSERT( stream );
485 *error = FT_Err_Ok;
487 if ( stream->pos + 1 < stream->size )
489 if ( stream->read )
491 if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
492 goto Fail;
494 p = reads;
496 else
498 p = stream->base + stream->pos;
501 if ( p )
502 result = FT_NEXT_SHORT( p );
504 else
505 goto Fail;
507 stream->pos += 2;
509 return result;
511 Fail:
512 *error = FT_Err_Invalid_Stream_Operation;
513 FT_ERROR(( "FT_Stream_ReadShort:"
514 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
515 stream->pos, stream->size ));
517 return 0;
521 FT_BASE_DEF( FT_Short )
522 FT_Stream_ReadShortLE( FT_Stream stream,
523 FT_Error* error )
525 FT_Byte reads[2];
526 FT_Byte* p = 0;
527 FT_Short result = 0;
530 FT_ASSERT( stream );
532 *error = FT_Err_Ok;
534 if ( stream->pos + 1 < stream->size )
536 if ( stream->read )
538 if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
539 goto Fail;
541 p = reads;
543 else
545 p = stream->base + stream->pos;
548 if ( p )
549 result = FT_NEXT_SHORT_LE( p );
551 else
552 goto Fail;
554 stream->pos += 2;
556 return result;
558 Fail:
559 *error = FT_Err_Invalid_Stream_Operation;
560 FT_ERROR(( "FT_Stream_ReadShortLE:"
561 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
562 stream->pos, stream->size ));
564 return 0;
568 FT_BASE_DEF( FT_Long )
569 FT_Stream_ReadOffset( FT_Stream stream,
570 FT_Error* error )
572 FT_Byte reads[3];
573 FT_Byte* p = 0;
574 FT_Long result = 0;
577 FT_ASSERT( stream );
579 *error = FT_Err_Ok;
581 if ( stream->pos + 2 < stream->size )
583 if ( stream->read )
585 if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
586 goto Fail;
588 p = reads;
590 else
592 p = stream->base + stream->pos;
595 if ( p )
596 result = FT_NEXT_OFF3( p );
598 else
599 goto Fail;
601 stream->pos += 3;
603 return result;
605 Fail:
606 *error = FT_Err_Invalid_Stream_Operation;
607 FT_ERROR(( "FT_Stream_ReadOffset:"
608 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
609 stream->pos, stream->size ));
611 return 0;
615 FT_BASE_DEF( FT_Long )
616 FT_Stream_ReadLong( FT_Stream stream,
617 FT_Error* error )
619 FT_Byte reads[4];
620 FT_Byte* p = 0;
621 FT_Long result = 0;
624 FT_ASSERT( stream );
626 *error = FT_Err_Ok;
628 if ( stream->pos + 3 < stream->size )
630 if ( stream->read )
632 if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
633 goto Fail;
635 p = reads;
637 else
639 p = stream->base + stream->pos;
642 if ( p )
643 result = FT_NEXT_LONG( p );
645 else
646 goto Fail;
648 stream->pos += 4;
650 return result;
652 Fail:
653 *error = FT_Err_Invalid_Stream_Operation;
654 FT_ERROR(( "FT_Stream_ReadLong:"
655 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
656 stream->pos, stream->size ));
658 return 0;
662 FT_BASE_DEF( FT_Long )
663 FT_Stream_ReadLongLE( FT_Stream stream,
664 FT_Error* error )
666 FT_Byte reads[4];
667 FT_Byte* p = 0;
668 FT_Long result = 0;
671 FT_ASSERT( stream );
673 *error = FT_Err_Ok;
675 if ( stream->pos + 3 < stream->size )
677 if ( stream->read )
679 if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
680 goto Fail;
682 p = reads;
684 else
686 p = stream->base + stream->pos;
689 if ( p )
690 result = FT_NEXT_LONG_LE( p );
692 else
693 goto Fail;
695 stream->pos += 4;
697 return result;
699 Fail:
700 *error = FT_Err_Invalid_Stream_Operation;
701 FT_ERROR(( "FT_Stream_ReadLongLE:"
702 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
703 stream->pos, stream->size ));
705 return 0;
709 FT_BASE_DEF( FT_Error )
710 FT_Stream_ReadFields( FT_Stream stream,
711 const FT_Frame_Field* fields,
712 void* structure )
714 FT_Error error;
715 FT_Bool frame_accessed = 0;
716 FT_Byte* cursor;
718 if ( !fields || !stream )
719 return FT_Err_Invalid_Argument;
721 cursor = stream->cursor;
723 error = FT_Err_Ok;
726 FT_ULong value;
727 FT_Int sign_shift;
728 FT_Byte* p;
731 switch ( fields->value )
733 case ft_frame_start: /* access a new frame */
734 error = FT_Stream_EnterFrame( stream, fields->offset );
735 if ( error )
736 goto Exit;
738 frame_accessed = 1;
739 cursor = stream->cursor;
740 fields++;
741 continue; /* loop! */
743 case ft_frame_bytes: /* read a byte sequence */
744 case ft_frame_skip: /* skip some bytes */
746 FT_UInt len = fields->size;
749 if ( cursor + len > stream->limit )
751 error = FT_Err_Invalid_Stream_Operation;
752 goto Exit;
755 if ( fields->value == ft_frame_bytes )
757 p = (FT_Byte*)structure + fields->offset;
758 FT_MEM_COPY( p, cursor, len );
760 cursor += len;
761 fields++;
762 continue;
765 case ft_frame_byte:
766 case ft_frame_schar: /* read a single byte */
767 value = FT_NEXT_BYTE(cursor);
768 sign_shift = 24;
769 break;
771 case ft_frame_short_be:
772 case ft_frame_ushort_be: /* read a 2-byte big-endian short */
773 value = FT_NEXT_USHORT(cursor);
774 sign_shift = 16;
775 break;
777 case ft_frame_short_le:
778 case ft_frame_ushort_le: /* read a 2-byte little-endian short */
779 value = FT_NEXT_USHORT_LE(cursor);
780 sign_shift = 16;
781 break;
783 case ft_frame_long_be:
784 case ft_frame_ulong_be: /* read a 4-byte big-endian long */
785 value = FT_NEXT_ULONG(cursor);
786 sign_shift = 0;
787 break;
789 case ft_frame_long_le:
790 case ft_frame_ulong_le: /* read a 4-byte little-endian long */
791 value = FT_NEXT_ULONG_LE(cursor);
792 sign_shift = 0;
793 break;
795 case ft_frame_off3_be:
796 case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
797 value = FT_NEXT_UOFF3(cursor);
798 sign_shift = 8;
799 break;
801 case ft_frame_off3_le:
802 case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
803 value = FT_NEXT_UOFF3_LE(cursor);
804 sign_shift = 8;
805 break;
807 default:
808 /* otherwise, exit the loop */
809 stream->cursor = cursor;
810 goto Exit;
813 /* now, compute the signed value is necessary */
814 if ( fields->value & FT_FRAME_OP_SIGNED )
815 value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
817 /* finally, store the value in the object */
819 p = (FT_Byte*)structure + fields->offset;
820 switch ( fields->size )
822 case (8 / FT_CHAR_BIT):
823 *(FT_Byte*)p = (FT_Byte)value;
824 break;
826 case (16 / FT_CHAR_BIT):
827 *(FT_UShort*)p = (FT_UShort)value;
828 break;
830 case (32 / FT_CHAR_BIT):
831 *(FT_UInt32*)p = (FT_UInt32)value;
832 break;
834 default: /* for 64-bit systems */
835 *(FT_ULong*)p = (FT_ULong)value;
838 /* go to next field */
839 fields++;
841 while ( 1 );
843 Exit:
844 /* close the frame if it was opened by this read */
845 if ( frame_accessed )
846 FT_Stream_ExitFrame( stream );
848 return error;
852 /* END */