PcxDecode.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * The Python Imaging Library.
  3. * $Id$
  4. *
  5. * decoder for PCX image data.
  6. *
  7. * history:
  8. * 95-09-14 fl Created
  9. *
  10. * Copyright (c) Fredrik Lundh 1995.
  11. * Copyright (c) Secret Labs AB 1997.
  12. *
  13. * See the README file for information on usage and redistribution.
  14. */
  15. #include "Imaging.h"
  16. int
  17. ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
  18. UINT8 n;
  19. UINT8 *ptr;
  20. if ((state->xsize * state->bits + 7) / 8 > state->bytes) {
  21. state->errcode = IMAGING_CODEC_OVERRUN;
  22. return -1;
  23. }
  24. ptr = buf;
  25. for (;;) {
  26. if (bytes < 1) {
  27. return ptr - buf;
  28. }
  29. if ((*ptr & 0xC0) == 0xC0) {
  30. /* Run */
  31. if (bytes < 2) {
  32. return ptr - buf;
  33. }
  34. n = ptr[0] & 0x3F;
  35. while (n > 0) {
  36. if (state->x >= state->bytes) {
  37. state->errcode = IMAGING_CODEC_OVERRUN;
  38. break;
  39. }
  40. state->buffer[state->x++] = ptr[1];
  41. n--;
  42. }
  43. ptr += 2;
  44. bytes -= 2;
  45. } else {
  46. /* Literal */
  47. state->buffer[state->x++] = ptr[0];
  48. ptr++;
  49. bytes--;
  50. }
  51. if (state->x >= state->bytes) {
  52. if (state->bytes % state->xsize && state->bytes > state->xsize) {
  53. int bands = state->bytes / state->xsize;
  54. int stride = state->bytes / bands;
  55. int i;
  56. for (i = 1; i < bands; i++) { // note -- skipping first band
  57. memmove(
  58. &state->buffer[i * state->xsize],
  59. &state->buffer[i * stride],
  60. state->xsize);
  61. }
  62. }
  63. /* Got a full line, unpack it */
  64. state->shuffle(
  65. (UINT8 *)im->image[state->y + state->yoff] +
  66. state->xoff * im->pixelsize,
  67. state->buffer,
  68. state->xsize);
  69. state->x = 0;
  70. if (++state->y >= state->ysize) {
  71. /* End of file (errcode = 0) */
  72. return -1;
  73. }
  74. }
  75. }
  76. }