ftstream.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /***************************************************************************/
  2. /* */
  3. /* ftstream.c */
  4. /* */
  5. /* I/O stream support (body). */
  6. /* */
  7. /* Copyright 2000-2001, 2002 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. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_INTERNAL_STREAM_H
  19. #include FT_INTERNAL_DEBUG_H
  20. /*************************************************************************/
  21. /* */
  22. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  23. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  24. /* messages during execution. */
  25. /* */
  26. #undef FT_COMPONENT
  27. #define FT_COMPONENT trace_stream
  28. FT_BASE_DEF( void )
  29. FT_Stream_OpenMemory( FT_Stream stream,
  30. const FT_Byte* base,
  31. FT_ULong size )
  32. {
  33. stream->base = (FT_Byte*) base;
  34. stream->size = size;
  35. stream->pos = 0;
  36. stream->cursor = 0;
  37. stream->read = 0;
  38. stream->close = 0;
  39. }
  40. FT_BASE_DEF( void )
  41. FT_Stream_Close( FT_Stream stream )
  42. {
  43. if ( stream && stream->close )
  44. {
  45. stream->close( stream );
  46. stream->close = NULL;
  47. }
  48. }
  49. FT_BASE_DEF( FT_Error )
  50. FT_Stream_Seek( FT_Stream stream,
  51. FT_ULong pos )
  52. {
  53. FT_Error error = FT_Err_Ok;
  54. stream->pos = pos;
  55. if ( stream->read )
  56. {
  57. if ( stream->read( stream, pos, 0, 0 ) )
  58. {
  59. FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  60. pos, stream->size ));
  61. error = FT_Err_Invalid_Stream_Operation;
  62. }
  63. }
  64. /* note that seeking to the first position after the file is valid */
  65. else if ( pos > stream->size )
  66. {
  67. FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  68. pos, stream->size ));
  69. error = FT_Err_Invalid_Stream_Operation;
  70. }
  71. return error;
  72. }
  73. FT_BASE_DEF( FT_Error )
  74. FT_Stream_Skip( FT_Stream stream,
  75. FT_Long distance )
  76. {
  77. return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );
  78. }
  79. FT_BASE_DEF( FT_Long )
  80. FT_Stream_Pos( FT_Stream stream )
  81. {
  82. return stream->pos;
  83. }
  84. FT_BASE_DEF( FT_Error )
  85. FT_Stream_Read( FT_Stream stream,
  86. FT_Byte* buffer,
  87. FT_ULong count )
  88. {
  89. return FT_Stream_ReadAt( stream, stream->pos, buffer, count );
  90. }
  91. FT_BASE_DEF( FT_Error )
  92. FT_Stream_ReadAt( FT_Stream stream,
  93. FT_ULong pos,
  94. FT_Byte* buffer,
  95. FT_ULong count )
  96. {
  97. FT_Error error = FT_Err_Ok;
  98. FT_ULong read_bytes;
  99. if ( pos >= stream->size )
  100. {
  101. FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  102. pos, stream->size ));
  103. return FT_Err_Invalid_Stream_Operation;
  104. }
  105. if ( stream->read )
  106. read_bytes = stream->read( stream, pos, buffer, count );
  107. else
  108. {
  109. read_bytes = stream->size - pos;
  110. if ( read_bytes > count )
  111. read_bytes = count;
  112. FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
  113. }
  114. stream->pos = pos + read_bytes;
  115. if ( read_bytes < count )
  116. {
  117. FT_ERROR(( "FT_Stream_ReadAt:" ));
  118. FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
  119. count, read_bytes ));
  120. error = FT_Err_Invalid_Stream_Operation;
  121. }
  122. return error;
  123. }
  124. FT_BASE_DEF( FT_Error )
  125. FT_Stream_ExtractFrame( FT_Stream stream,
  126. FT_ULong count,
  127. FT_Byte** pbytes )
  128. {
  129. FT_Error error;
  130. error = FT_Stream_EnterFrame( stream, count );
  131. if ( !error )
  132. {
  133. *pbytes = (FT_Byte*)stream->cursor;
  134. /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
  135. stream->cursor = 0;
  136. stream->limit = 0;
  137. }
  138. return error;
  139. }
  140. FT_BASE_DEF( void )
  141. FT_Stream_ReleaseFrame( FT_Stream stream,
  142. FT_Byte** pbytes )
  143. {
  144. if ( stream->read )
  145. {
  146. FT_Memory memory = stream->memory;
  147. FT_FREE( *pbytes );
  148. }
  149. *pbytes = 0;
  150. }
  151. FT_BASE_DEF( FT_Error )
  152. FT_Stream_EnterFrame( FT_Stream stream,
  153. FT_ULong count )
  154. {
  155. FT_Error error = FT_Err_Ok;
  156. FT_ULong read_bytes;
  157. /* check for nested frame access */
  158. FT_ASSERT( stream && stream->cursor == 0 );
  159. if ( stream->read )
  160. {
  161. /* allocate the frame in memory */
  162. FT_Memory memory = stream->memory;
  163. if ( FT_ALLOC( stream->base, count ) )
  164. goto Exit;
  165. /* read it */
  166. read_bytes = stream->read( stream, stream->pos,
  167. stream->base, count );
  168. if ( read_bytes < count )
  169. {
  170. FT_ERROR(( "FT_Stream_EnterFrame:" ));
  171. FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
  172. count, read_bytes ));
  173. FT_FREE( stream->base );
  174. error = FT_Err_Invalid_Stream_Operation;
  175. }
  176. stream->cursor = stream->base;
  177. stream->limit = stream->cursor + count;
  178. stream->pos += read_bytes;
  179. }
  180. else
  181. {
  182. /* check current and new position */
  183. if ( stream->pos >= stream->size ||
  184. stream->pos + count > stream->size )
  185. {
  186. FT_ERROR(( "FT_Stream_EnterFrame:" ));
  187. FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
  188. stream->pos, count, stream->size ));
  189. error = FT_Err_Invalid_Stream_Operation;
  190. goto Exit;
  191. }
  192. /* set cursor */
  193. stream->cursor = stream->base + stream->pos;
  194. stream->limit = stream->cursor + count;
  195. stream->pos += count;
  196. }
  197. Exit:
  198. return error;
  199. }
  200. FT_BASE_DEF( void )
  201. FT_Stream_ExitFrame( FT_Stream stream )
  202. {
  203. /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */
  204. /* that it is possible to access a frame of length 0 in */
  205. /* some weird fonts (usually, when accessing an array of */
  206. /* 0 records, like in some strange kern tables). */
  207. /* */
  208. /* In this case, the loader code handles the 0-length table */
  209. /* gracefully; however, stream.cursor is really set to 0 by the */
  210. /* FT_Stream_EnterFrame() call, and this is not an error. */
  211. /* */
  212. FT_ASSERT( stream );
  213. if ( stream->read )
  214. {
  215. FT_Memory memory = stream->memory;
  216. FT_FREE( stream->base );
  217. }
  218. stream->cursor = 0;
  219. stream->limit = 0;
  220. }
  221. FT_BASE_DEF( FT_Char )
  222. FT_Stream_GetChar( FT_Stream stream )
  223. {
  224. FT_Char result;
  225. FT_ASSERT( stream && stream->cursor );
  226. result = 0;
  227. if ( stream->cursor < stream->limit )
  228. result = *stream->cursor++;
  229. return result;
  230. }
  231. FT_BASE_DEF( FT_Short )
  232. FT_Stream_GetShort( FT_Stream stream )
  233. {
  234. FT_Byte* p;
  235. FT_Short result;
  236. FT_ASSERT( stream && stream->cursor );
  237. result = 0;
  238. p = stream->cursor;
  239. if ( p + 1 < stream->limit )
  240. result = FT_NEXT_SHORT( p );
  241. stream->cursor = p;
  242. return result;
  243. }
  244. FT_BASE_DEF( FT_Short )
  245. FT_Stream_GetShortLE( FT_Stream stream )
  246. {
  247. FT_Byte* p;
  248. FT_Short result;
  249. FT_ASSERT( stream && stream->cursor );
  250. result = 0;
  251. p = stream->cursor;
  252. if ( p + 1 < stream->limit )
  253. result = FT_NEXT_SHORT_LE( p );
  254. stream->cursor = p;
  255. return result;
  256. }
  257. FT_BASE_DEF( FT_Long )
  258. FT_Stream_GetOffset( FT_Stream stream )
  259. {
  260. FT_Byte* p;
  261. FT_Long result;
  262. FT_ASSERT( stream && stream->cursor );
  263. result = 0;
  264. p = stream->cursor;
  265. if ( p + 2 < stream->limit )
  266. result = FT_NEXT_OFF3( p );
  267. stream->cursor = p;
  268. return result;
  269. }
  270. FT_BASE_DEF( FT_Long )
  271. FT_Stream_GetLong( FT_Stream stream )
  272. {
  273. FT_Byte* p;
  274. FT_Long result;
  275. FT_ASSERT( stream && stream->cursor );
  276. result = 0;
  277. p = stream->cursor;
  278. if ( p + 3 < stream->limit )
  279. result = FT_NEXT_LONG( p );
  280. stream->cursor = p;
  281. return result;
  282. }
  283. FT_BASE_DEF( FT_Long )
  284. FT_Stream_GetLongLE( FT_Stream stream )
  285. {
  286. FT_Byte* p;
  287. FT_Long result;
  288. FT_ASSERT( stream && stream->cursor );
  289. result = 0;
  290. p = stream->cursor;
  291. if ( p + 3 < stream->limit )
  292. result = FT_NEXT_LONG_LE( p );
  293. stream->cursor = p;
  294. return result;
  295. }
  296. FT_BASE_DEF( FT_Char )
  297. FT_Stream_ReadChar( FT_Stream stream,
  298. FT_Error* error )
  299. {
  300. FT_Byte result = 0;
  301. FT_ASSERT( stream );
  302. *error = FT_Err_Ok;
  303. if ( stream->read )
  304. {
  305. if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
  306. goto Fail;
  307. }
  308. else
  309. {
  310. if ( stream->pos < stream->size )
  311. result = stream->base[stream->pos];
  312. else
  313. goto Fail;
  314. }
  315. stream->pos++;
  316. return result;
  317. Fail:
  318. *error = FT_Err_Invalid_Stream_Operation;
  319. FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  320. stream->pos, stream->size ));
  321. return 0;
  322. }
  323. FT_BASE_DEF( FT_Short )
  324. FT_Stream_ReadShort( FT_Stream stream,
  325. FT_Error* error )
  326. {
  327. FT_Byte reads[2];
  328. FT_Byte* p = 0;
  329. FT_Short result = 0;
  330. FT_ASSERT( stream );
  331. *error = FT_Err_Ok;
  332. if ( stream->pos + 1 < stream->size )
  333. {
  334. if ( stream->read )
  335. {
  336. if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
  337. goto Fail;
  338. p = reads;
  339. }
  340. else
  341. {
  342. p = stream->base + stream->pos;
  343. }
  344. if ( p )
  345. result = FT_NEXT_SHORT( p );
  346. }
  347. else
  348. goto Fail;
  349. stream->pos += 2;
  350. return result;
  351. Fail:
  352. *error = FT_Err_Invalid_Stream_Operation;
  353. FT_ERROR(( "FT_Stream_ReadShort:" ));
  354. FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  355. stream->pos, stream->size ));
  356. return 0;
  357. }
  358. FT_BASE_DEF( FT_Short )
  359. FT_Stream_ReadShortLE( FT_Stream stream,
  360. FT_Error* error )
  361. {
  362. FT_Byte reads[2];
  363. FT_Byte* p = 0;
  364. FT_Short result = 0;
  365. FT_ASSERT( stream );
  366. *error = FT_Err_Ok;
  367. if ( stream->pos + 1 < stream->size )
  368. {
  369. if ( stream->read )
  370. {
  371. if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
  372. goto Fail;
  373. p = reads;
  374. }
  375. else
  376. {
  377. p = stream->base + stream->pos;
  378. }
  379. if ( p )
  380. result = FT_NEXT_SHORT_LE( p );
  381. }
  382. else
  383. goto Fail;
  384. stream->pos += 2;
  385. return result;
  386. Fail:
  387. *error = FT_Err_Invalid_Stream_Operation;
  388. FT_ERROR(( "FT_Stream_ReadShortLE:" ));
  389. FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  390. stream->pos, stream->size ));
  391. return 0;
  392. }
  393. FT_BASE_DEF( FT_Long )
  394. FT_Stream_ReadOffset( FT_Stream stream,
  395. FT_Error* error )
  396. {
  397. FT_Byte reads[3];
  398. FT_Byte* p = 0;
  399. FT_Long result = 0;
  400. FT_ASSERT( stream );
  401. *error = FT_Err_Ok;
  402. if ( stream->pos + 2 < stream->size )
  403. {
  404. if ( stream->read )
  405. {
  406. if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
  407. goto Fail;
  408. p = reads;
  409. }
  410. else
  411. {
  412. p = stream->base + stream->pos;
  413. }
  414. if ( p )
  415. result = FT_NEXT_OFF3( p );
  416. }
  417. else
  418. goto Fail;
  419. stream->pos += 3;
  420. return result;
  421. Fail:
  422. *error = FT_Err_Invalid_Stream_Operation;
  423. FT_ERROR(( "FT_Stream_ReadOffset:" ));
  424. FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  425. stream->pos, stream->size ));
  426. return 0;
  427. }
  428. FT_BASE_DEF( FT_Long )
  429. FT_Stream_ReadLong( FT_Stream stream,
  430. FT_Error* error )
  431. {
  432. FT_Byte reads[4];
  433. FT_Byte* p = 0;
  434. FT_Long result = 0;
  435. FT_ASSERT( stream );
  436. *error = FT_Err_Ok;
  437. if ( stream->pos + 3 < stream->size )
  438. {
  439. if ( stream->read )
  440. {
  441. if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
  442. goto Fail;
  443. p = reads;
  444. }
  445. else
  446. {
  447. p = stream->base + stream->pos;
  448. }
  449. if ( p )
  450. result = FT_NEXT_LONG( p );
  451. }
  452. else
  453. goto Fail;
  454. stream->pos += 4;
  455. return result;
  456. Fail:
  457. FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  458. stream->pos, stream->size ));
  459. *error = FT_Err_Invalid_Stream_Operation;
  460. return 0;
  461. }
  462. FT_BASE_DEF( FT_Long )
  463. FT_Stream_ReadLongLE( FT_Stream stream,
  464. FT_Error* error )
  465. {
  466. FT_Byte reads[4];
  467. FT_Byte* p = 0;
  468. FT_Long result = 0;
  469. FT_ASSERT( stream );
  470. *error = FT_Err_Ok;
  471. if ( stream->pos + 3 < stream->size )
  472. {
  473. if ( stream->read )
  474. {
  475. if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
  476. goto Fail;
  477. p = reads;
  478. }
  479. else
  480. {
  481. p = stream->base + stream->pos;
  482. }
  483. if ( p )
  484. result = FT_NEXT_LONG_LE( p );
  485. }
  486. else
  487. goto Fail;
  488. stream->pos += 4;
  489. return result;
  490. Fail:
  491. FT_ERROR(( "FT_Stream_ReadLongLE:" ));
  492. FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
  493. stream->pos, stream->size ));
  494. *error = FT_Err_Invalid_Stream_Operation;
  495. return 0;
  496. }
  497. FT_BASE_DEF( FT_Error )
  498. FT_Stream_ReadFields( FT_Stream stream,
  499. const FT_Frame_Field* fields,
  500. void* structure )
  501. {
  502. FT_Error error;
  503. FT_Bool frame_accessed = 0;
  504. FT_Byte* cursor = stream->cursor;
  505. if ( !fields || !stream )
  506. return FT_Err_Invalid_Argument;
  507. error = FT_Err_Ok;
  508. do
  509. {
  510. FT_ULong value;
  511. FT_Int sign_shift;
  512. FT_Byte* p;
  513. switch ( fields->value )
  514. {
  515. case ft_frame_start: /* access a new frame */
  516. error = FT_Stream_EnterFrame( stream, fields->offset );
  517. if ( error )
  518. goto Exit;
  519. frame_accessed = 1;
  520. cursor = stream->cursor;
  521. fields++;
  522. continue; /* loop! */
  523. case ft_frame_bytes: /* read a byte sequence */
  524. case ft_frame_skip: /* skip some bytes */
  525. {
  526. FT_UInt len = fields->size;
  527. if ( cursor + len > stream->limit )
  528. {
  529. error = FT_Err_Invalid_Stream_Operation;
  530. goto Exit;
  531. }
  532. if ( fields->value == ft_frame_bytes )
  533. {
  534. p = (FT_Byte*)structure + fields->offset;
  535. FT_MEM_COPY( p, cursor, len );
  536. }
  537. cursor += len;
  538. fields++;
  539. continue;
  540. }
  541. case ft_frame_byte:
  542. case ft_frame_schar: /* read a single byte */
  543. value = FT_NEXT_BYTE(cursor);
  544. sign_shift = 24;
  545. break;
  546. case ft_frame_short_be:
  547. case ft_frame_ushort_be: /* read a 2-byte big-endian short */
  548. value = FT_NEXT_USHORT(cursor);
  549. sign_shift = 16;
  550. break;
  551. case ft_frame_short_le:
  552. case ft_frame_ushort_le: /* read a 2-byte little-endian short */
  553. value = FT_NEXT_USHORT_LE(cursor);
  554. sign_shift = 16;
  555. break;
  556. case ft_frame_long_be:
  557. case ft_frame_ulong_be: /* read a 4-byte big-endian long */
  558. value = FT_NEXT_ULONG(cursor);
  559. sign_shift = 0;
  560. break;
  561. case ft_frame_long_le:
  562. case ft_frame_ulong_le: /* read a 4-byte little-endian long */
  563. value = FT_NEXT_ULONG_LE(cursor);
  564. sign_shift = 0;
  565. break;
  566. case ft_frame_off3_be:
  567. case ft_frame_uoff3_be: /* read a 3-byte big-endian long */
  568. value = FT_NEXT_UOFF3(cursor);
  569. sign_shift = 8;
  570. break;
  571. case ft_frame_off3_le:
  572. case ft_frame_uoff3_le: /* read a 3-byte little-endian long */
  573. value = FT_NEXT_UOFF3_LE(cursor);
  574. sign_shift = 8;
  575. break;
  576. default:
  577. /* otherwise, exit the loop */
  578. stream->cursor = cursor;
  579. goto Exit;
  580. }
  581. /* now, compute the signed value is necessary */
  582. if ( fields->value & FT_FRAME_OP_SIGNED )
  583. value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );
  584. /* finally, store the value in the object */
  585. p = (FT_Byte*)structure + fields->offset;
  586. switch ( fields->size )
  587. {
  588. case 1:
  589. *(FT_Byte*)p = (FT_Byte)value;
  590. break;
  591. case 2:
  592. *(FT_UShort*)p = (FT_UShort)value;
  593. break;
  594. case 4:
  595. *(FT_UInt32*)p = (FT_UInt32)value;
  596. break;
  597. default: /* for 64-bit systems */
  598. *(FT_ULong*)p = (FT_ULong)value;
  599. }
  600. /* go to next field */
  601. fields++;
  602. }
  603. while ( 1 );
  604. Exit:
  605. /* close the frame if it was opened by this read */
  606. if ( frame_accessed )
  607. FT_Stream_ExitFrame( stream );
  608. return error;
  609. }
  610. /* END */