Pillow

Форк
0
/
SunRleDecode.c 
140 строк · 3.6 Кб
1
/*
2
 * THIS IS WORK IN PROGRESS
3
 *
4
 * The Python Imaging Library.
5
 * $Id$
6
 *
7
 * decoder for SUN RLE data.
8
 *
9
 * history:
10
 *      97-01-04 fl     Created
11
 *
12
 * Copyright (c) Fredrik Lundh 1997.
13
 * Copyright (c) Secret Labs AB 1997.
14
 *
15
 * See the README file for information on usage and redistribution.
16
 */
17

18
#include "Imaging.h"
19

20
int
21
ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
22
    int n;
23
    UINT8 *ptr;
24
    UINT8 extra_data = 0;
25
    UINT8 extra_bytes = 0;
26

27
    ptr = buf;
28

29
    for (;;) {
30
        if (bytes < 1) {
31
            return ptr - buf;
32
        }
33

34
        if (ptr[0] == 0x80) {
35
            if (bytes < 2) {
36
                break;
37
            }
38

39
            n = ptr[1];
40

41
            if (n == 0) {
42
                /* Literal 0x80 (2 bytes) */
43
                n = 1;
44

45
                state->buffer[state->x] = 0x80;
46

47
                ptr += 2;
48
                bytes -= 2;
49

50
            } else {
51
                /* Run (3 bytes) */
52
                if (bytes < 3) {
53
                    break;
54
                }
55

56
                /* from (https://www.fileformat.info/format/sunraster/egff.htm)
57

58
                   For example, a run of 100 pixels with the value of
59
                   0Ah would encode as the values 80h 64h 0Ah. A
60
                   single pixel value of 80h would encode as the
61
                   values 80h 00h. The four unencoded bytes 12345678h
62
                   would be stored in the RLE stream as 12h 34h 56h
63
                   78h.  100 pixels, n=100, not 100 pixels, n=99.
64

65
                   But Wait! There's More!
66
                   (https://www.fileformat.info/format/sunraster/spec/598a59c4fac64c52897585d390d86360/view.htm)
67

68
                   If the first byte is 0x80, and the second byte is
69
                   not zero, the record is three bytes long. The
70
                   second byte is a count and the third byte is a
71
                   value. Output (count+1) pixels of that value.
72

73
                   2 specs, same site, but Imagemagick and GIMP seem
74
                   to agree on the second one.
75
                */
76
                n += 1;
77

78
                if (state->x + n > state->bytes) {
79
                    extra_bytes = n; /* full value */
80
                    n = state->bytes - state->x;
81
                    extra_bytes -= n;
82
                    extra_data = ptr[2];
83
                }
84

85
                memset(state->buffer + state->x, ptr[2], n);
86

87
                ptr += 3;
88
                bytes -= 3;
89
            }
90

91
        } else {
92
            /* Literal byte */
93
            n = 1;
94

95
            state->buffer[state->x] = ptr[0];
96

97
            ptr += 1;
98
            bytes -= 1;
99
        }
100

101
        for (;;) {
102
            state->x += n;
103

104
            if (state->x >= state->bytes) {
105
                /* Got a full line, unpack it */
106
                state->shuffle(
107
                    (UINT8 *)im->image[state->y + state->yoff] +
108
                        state->xoff * im->pixelsize,
109
                    state->buffer,
110
                    state->xsize
111
                );
112

113
                state->x = 0;
114

115
                if (++state->y >= state->ysize) {
116
                    /* End of file (errcode = 0) */
117
                    return -1;
118
                }
119
            }
120

121
            if (extra_bytes == 0) {
122
                break;
123
            }
124

125
            if (state->x > 0) {
126
                break;  // assert
127
            }
128

129
            if (extra_bytes >= state->bytes) {
130
                n = state->bytes;
131
            } else {
132
                n = extra_bytes;
133
            }
134
            memset(state->buffer + state->x, extra_data, n);
135
            extra_bytes -= n;
136
        }
137
    }
138

139
    return ptr - buf;
140
}
141

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.