Pillow
130 строк · 3.1 Кб
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
17#include "Imaging.h"18
19int
20ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {21int n, depth;22UINT8 *ptr;23int extra_bytes = 0;24
25ptr = buf;26
27if (state->state == 0) {28/* check image orientation */29if (state->ystep < 0) {30state->y = state->ysize - 1;31state->ystep = -1;32} else {33state->ystep = 1;34}35
36state->state = 1;37}38
39depth = state->count;40
41for (;;) {42if (bytes < 1) {43return ptr - buf;44}45
46n = depth * ((ptr[0] & 0x7f) + 1);47if (ptr[0] & 0x80) {48/* Run (1 + pixelsize bytes) */49if (bytes < 1 + depth) {50break;51}52
53if (state->x + n > state->bytes) {54state->errcode = IMAGING_CODEC_OVERRUN;55return -1;56}57
58if (depth == 1) {59memset(state->buffer + state->x, ptr[1], n);60} else {61int i;62for (i = 0; i < n; i += depth) {63memcpy(state->buffer + state->x + i, ptr + 1, depth);64}65}66
67ptr += 1 + depth;68bytes -= 1 + depth;69} else {70/* Literal (1+n+1 bytes block) */71if (bytes < 1 + n) {72break;73}74
75if (state->x + n > state->bytes) {76extra_bytes = n; /* full value */77n = state->bytes - state->x;78extra_bytes -= n;79}80
81memcpy(state->buffer + state->x, ptr + 1, n);82
83ptr += 1 + n;84bytes -= 1 + n;85}86
87for (;;) {88state->x += n;89
90if (state->x >= state->bytes) {91/* Got a full line, unpack it */92state->shuffle(93(UINT8 *)im->image[state->y + state->yoff] +94state->xoff * im->pixelsize,95state->buffer,96state->xsize97);98
99state->x = 0;100
101state->y += state->ystep;102
103if (state->y < 0 || state->y >= state->ysize) {104/* End of file (errcode = 0) */105return -1;106}107}108
109if (extra_bytes == 0) {110break;111}112
113if (state->x > 0) {114break; // assert115}116
117if (extra_bytes >= state->bytes) {118n = state->bytes;119} else {120n = extra_bytes;121}122memcpy(state->buffer + state->x, ptr, n);123ptr += n;124bytes -= n;125extra_bytes -= n;126}127}128
129return ptr - buf;130}
131