PcxDecode.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. {
  19. UINT8 n;
  20. UINT8* ptr;
  21. if (strcmp(im->mode, "1") == 0 && state->xsize > state->bytes * 8) {
  22. state->errcode = IMAGING_CODEC_OVERRUN;
  23. return -1;
  24. } else if (strcmp(im->mode, "P") == 0 && state->xsize > state->bytes) {
  25. state->errcode = IMAGING_CODEC_OVERRUN;
  26. return -1;
  27. }
  28. ptr = buf;
  29. for (;;) {
  30. if (bytes < 1)
  31. return ptr - buf;
  32. if ((*ptr & 0xC0) == 0xC0) {
  33. /* Run */
  34. if (bytes < 2)
  35. return ptr - buf;
  36. n = ptr[0] & 0x3F;
  37. while (n > 0) {
  38. if (state->x >= state->bytes) {
  39. state->errcode = IMAGING_CODEC_OVERRUN;
  40. break;
  41. }
  42. state->buffer[state->x++] = ptr[1];
  43. n--;
  44. }
  45. ptr += 2; bytes -= 2;
  46. } else {
  47. /* Literal */
  48. state->buffer[state->x++] = ptr[0];
  49. ptr++; 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(&state->buffer[i*state->xsize],
  58. &state->buffer[i*stride],
  59. state->xsize);
  60. }
  61. }
  62. /* Got a full line, unpack it */
  63. state->shuffle((UINT8*) im->image[state->y + state->yoff] +
  64. state->xoff * im->pixelsize, state->buffer,
  65. state->xsize);
  66. state->x = 0;
  67. if (++state->y >= state->ysize) {
  68. /* End of file (errcode = 0) */
  69. return -1;
  70. }
  71. }
  72. }
  73. }