TgaRleDecode.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * The Python Imaging Library.
  3. * $Id$
  4. *
  5. * decoder for Targa RLE data.
  6. *
  7. * history:
  8. * 97-01-04 fl created
  9. * 98-09-11 fl don't one byte per pixel; take orientation into account
  10. *
  11. * Copyright (c) Fredrik Lundh 1997.
  12. * Copyright (c) Secret Labs AB 1997-98.
  13. *
  14. * See the README file for information on usage and redistribution.
  15. */
  16. #include "Imaging.h"
  17. int
  18. ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
  19. UINT8* buf, Py_ssize_t bytes)
  20. {
  21. int n, depth;
  22. UINT8* ptr;
  23. ptr = buf;
  24. if (state->state == 0) {
  25. /* check image orientation */
  26. if (state->ystep < 0) {
  27. state->y = state->ysize-1;
  28. state->ystep = -1;
  29. } else
  30. state->ystep = 1;
  31. state->state = 1;
  32. }
  33. depth = state->count;
  34. for (;;) {
  35. if (bytes < 1)
  36. return ptr - buf;
  37. if (ptr[0] & 0x80) {
  38. /* Run (1 + pixelsize bytes) */
  39. if (bytes < 1 + depth)
  40. break;
  41. n = depth * ((ptr[0] & 0x7f) + 1);
  42. if (state->x + n > state->bytes) {
  43. state->errcode = IMAGING_CODEC_OVERRUN;
  44. return -1;
  45. }
  46. if (depth == 1)
  47. memset(state->buffer + state->x, ptr[1], n);
  48. else {
  49. int i;
  50. for (i = 0; i < n; i += depth)
  51. memcpy(state->buffer + state->x + i, ptr+1, depth);
  52. }
  53. ptr += 1 + depth;
  54. bytes -= 1 + depth;
  55. } else {
  56. /* Literal (1+n+1 bytes block) */
  57. n = depth * (ptr[0] + 1);
  58. if (bytes < 1 + n)
  59. break;
  60. if (state->x + n > state->bytes) {
  61. state->errcode = IMAGING_CODEC_OVERRUN;
  62. return -1;
  63. }
  64. memcpy(state->buffer + state->x, ptr + 1, n);
  65. ptr += 1 + n;
  66. bytes -= 1 + n;
  67. }
  68. state->x += n;
  69. if (state->x >= state->bytes) {
  70. /* Got a full line, unpack it */
  71. state->shuffle((UINT8*) im->image[state->y + state->yoff] +
  72. state->xoff * im->pixelsize, state->buffer,
  73. state->xsize);
  74. state->x = 0;
  75. state->y += state->ystep;
  76. if (state->y < 0 || state->y >= state->ysize) {
  77. /* End of file (errcode = 0) */
  78. return -1;
  79. }
  80. }
  81. }
  82. return ptr - buf;
  83. }