~ubuntu-branches/ubuntu/trusty/python-imaging/trusty

« back to all changes in this revision

Viewing changes to libImaging/Access.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-11-20 19:22:59 UTC
  • mfrom: (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091120192259-cmnfui5tv2jtq4xu
Tags: 1.1.7-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * The Python Imaging Library
3
 
 * $Id: Access.c 2134 2004-10-06 08:55:20Z fredrik $
 
3
 * $Id$
4
4
 *
5
5
 * imaging access objects
6
6
 *
7
 
 * an access object can convert image data on the fly
8
 
 *
9
 
 * history:
10
 
 * 98-12-29 fl  Created
11
 
 *
12
 
 * Copyright (c) Secret Labs AB 1998.
 
7
 * Copyright (c) Fredrik Lundh 2009.
13
8
 *
14
9
 * See the README file for information on usage and redistribution.
15
10
 */
17
12
 
18
13
#include "Imaging.h"
19
14
 
20
 
 
21
 
static void
22
 
access_destroy(ImagingAccess access)
23
 
{
24
 
    /* nop */
25
 
}
26
 
 
27
 
static int
28
 
access_getline(ImagingAccess access, char* buffer, int y)
29
 
{
30
 
    memcpy(buffer, access->im->image[y], access->im->linesize);
31
 
    return 1;
 
15
/* use Tests/make_hash.py to calculate these values */
 
16
#define ACCESS_TABLE_SIZE 21
 
17
#define ACCESS_TABLE_HASH 30197
 
18
 
 
19
static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE];
 
20
  
 
21
static inline UINT32
 
22
hash(const char* mode)
 
23
{
 
24
    UINT32 i = ACCESS_TABLE_HASH;
 
25
    while (*mode)
 
26
        i = ((i<<5) + i) ^ (UINT8) *mode++;
 
27
    return i % ACCESS_TABLE_SIZE;
 
28
}
 
29
 
 
30
static ImagingAccess
 
31
add_item(const char* mode)
 
32
{
 
33
    UINT32 i = hash(mode);
 
34
    /* printf("hash %s => %d\n", mode, i); */
 
35
    if (access_table[i].mode) {
 
36
        fprintf(stderr, "AccessInit: hash collision: %d for both %s and %s\n",
 
37
                i, mode, access_table[i].mode);
 
38
        exit(1);
 
39
    }
 
40
    access_table[i].mode = mode;
 
41
    return &access_table[i];
 
42
}
 
43
 
 
44
/* fetch pointer to pixel line */
 
45
 
 
46
static void*
 
47
line_8(Imaging im, int x, int y)
 
48
{
 
49
    return &im->image8[y][x];
 
50
}
 
51
 
 
52
static void*
 
53
line_16(Imaging im, int x, int y)
 
54
{
 
55
    return &im->image8[y][x+x];
 
56
}
 
57
 
 
58
static void*
 
59
line_32(Imaging im, int x, int y)
 
60
{
 
61
    return &im->image32[y][x];
 
62
}
 
63
 
 
64
/* fetch individual pixel */
 
65
 
 
66
static void
 
67
get_pixel(Imaging im, int x, int y, void* color)
 
68
{
 
69
    char* out = color;
 
70
 
 
71
    /* generic pixel access*/
 
72
 
 
73
    if (im->image8) {
 
74
        out[0] = im->image8[y][x];
 
75
    } else {
 
76
        UINT8* p = (UINT8*) &im->image32[y][x];
 
77
        if (im->type == IMAGING_TYPE_UINT8 && im->bands == 2) {
 
78
            out[0] = p[0];
 
79
            out[1] = p[3];
 
80
            return;
 
81
        }
 
82
        memcpy(out, p, im->pixelsize);
 
83
    }
 
84
}
 
85
 
 
86
static void
 
87
get_pixel_8(Imaging im, int x, int y, void* color)
 
88
{
 
89
    char* out = color;
 
90
    out[0] = im->image8[y][x];
 
91
}
 
92
 
 
93
static void
 
94
get_pixel_16L(Imaging im, int x, int y, void* color)
 
95
{
 
96
    UINT8* in = (UINT8*) &im->image[y][x+x];
 
97
    INT16* out = color;
 
98
#ifdef WORDS_BIGENDIAN
 
99
    out[0] = in[0] + (in[1]<<8);
 
100
#else
 
101
    out[0] = *(INT16*) in;
 
102
#endif
 
103
}
 
104
 
 
105
static void
 
106
get_pixel_16B(Imaging im, int x, int y, void* color)
 
107
{
 
108
    UINT8* in = (UINT8*) &im->image[y][x+x];
 
109
    INT16* out = color;
 
110
#ifdef WORDS_BIGENDIAN
 
111
    out[0] = *(INT16*) in;
 
112
#else
 
113
    out[0] = in[1] + (in[0]<<8);
 
114
#endif
 
115
}
 
116
 
 
117
static void
 
118
get_pixel_32(Imaging im, int x, int y, void* color)
 
119
{
 
120
    INT32* out = color;
 
121
    out[0] = im->image32[y][x];
 
122
}
 
123
 
 
124
static void
 
125
get_pixel_32L(Imaging im, int x, int y, void* color)
 
126
{
 
127
    UINT8* in = (UINT8*) &im->image[y][x*4];
 
128
    INT32* out = color;
 
129
#ifdef WORDS_BIGENDIAN
 
130
    out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24);
 
131
#else
 
132
    out[0] = *(INT32*) in;
 
133
#endif
 
134
}
 
135
 
 
136
static void
 
137
get_pixel_32B(Imaging im, int x, int y, void* color)
 
138
{
 
139
    UINT8* in = (UINT8*) &im->image[y][x*4];
 
140
    INT32* out = color;
 
141
#ifdef WORDS_BIGENDIAN
 
142
    out[0] = *(INT32*) in;
 
143
#else
 
144
    out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24);
 
145
#endif
 
146
}
 
147
 
 
148
/* store individual pixel */
 
149
 
 
150
static void
 
151
put_pixel(Imaging im, int x, int y, const void* color)
 
152
{
 
153
    if (im->image8)
 
154
        im->image8[y][x] = *((UINT8*) color);
 
155
    else
 
156
        im->image32[y][x] = *((INT32*) color);
 
157
}
 
158
 
 
159
static void
 
160
put_pixel_8(Imaging im, int x, int y, const void* color)
 
161
{
 
162
    im->image8[y][x] = *((UINT8*) color);
 
163
}
 
164
 
 
165
static void
 
166
put_pixel_16L(Imaging im, int x, int y, const void* color)
 
167
{
 
168
    const char* in = color;
 
169
    UINT8* out = (UINT8*) &im->image8[y][x+x];
 
170
    out[0] = in[0];
 
171
    out[1] = in[1];
 
172
}
 
173
 
 
174
static void
 
175
put_pixel_16B(Imaging im, int x, int y, const void* color)
 
176
{
 
177
    const char* in = color;
 
178
    UINT8* out = (UINT8*) &im->image8[y][x+x];
 
179
    out[0] = in[1];
 
180
    out[1] = in[0];
 
181
}
 
182
 
 
183
static void
 
184
put_pixel_32L(Imaging im, int x, int y, const void* color)
 
185
{
 
186
    const char* in = color;
 
187
    UINT8* out = (UINT8*) &im->image8[y][x*4];
 
188
    out[0] = in[0];
 
189
    out[1] = in[1];
 
190
    out[2] = in[2];
 
191
    out[3] = in[3];
 
192
}
 
193
 
 
194
static void
 
195
put_pixel_32B(Imaging im, int x, int y, const void* color)
 
196
{
 
197
    const char* in = color;
 
198
    UINT8* out = (UINT8*) &im->image8[y][x*4];
 
199
    out[0] = in[3];
 
200
    out[1] = in[2];
 
201
    out[2] = in[1];
 
202
    out[3] = in[0];
 
203
}
 
204
 
 
205
static void
 
206
put_pixel_32(Imaging im, int x, int y, const void* color)
 
207
{
 
208
    im->image32[y][x] = *((INT32*) color);
 
209
}
 
210
 
 
211
void
 
212
ImagingAccessInit()
 
213
{
 
214
#define ADD(mode_, line_, get_pixel_, put_pixel_)       \
 
215
    { ImagingAccess access = add_item(mode_);           \
 
216
        access->line = line_;                           \
 
217
        access->get_pixel = get_pixel_;                 \
 
218
        access->put_pixel = put_pixel_;                 \
 
219
    }
 
220
 
 
221
    /* populate access table */
 
222
    ADD("1", line_8, get_pixel_8, put_pixel_8);
 
223
    ADD("L", line_8, get_pixel_8, put_pixel_8);
 
224
    ADD("LA", line_32, get_pixel, put_pixel);
 
225
    ADD("I", line_32, get_pixel_32, put_pixel_32);
 
226
    ADD("I;16", line_16, get_pixel_16L, put_pixel_16L);
 
227
    ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L);
 
228
    ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B);
 
229
    ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L);
 
230
    ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B);
 
231
    ADD("F", line_32, get_pixel_32, put_pixel_32);
 
232
    ADD("P", line_8, get_pixel_8, put_pixel_8);
 
233
    ADD("PA", line_32, get_pixel, put_pixel);
 
234
    ADD("RGB", line_32, get_pixel_32, put_pixel_32);
 
235
    ADD("RGBA", line_32, get_pixel_32, put_pixel_32);
 
236
    ADD("RGBa", line_32, get_pixel_32, put_pixel_32);
 
237
    ADD("RGBX", line_32, get_pixel_32, put_pixel_32);
 
238
    ADD("CMYK", line_32, get_pixel_32, put_pixel_32);
 
239
    ADD("YCbCr", line_32, get_pixel_32, put_pixel_32);
32
240
}
33
241
 
34
242
ImagingAccess
35
243
ImagingAccessNew(Imaging im)
36
244
{
37
 
    /* Create a standard access object */
38
 
 
39
 
    ImagingAccess access;
40
 
 
41
 
    access = calloc(1, sizeof(struct ImagingAccessInstance));
42
 
    if (!access)
43
 
        return (ImagingAccess) ImagingError_MemoryError();
44
 
 
45
 
    access->im = im;
46
 
 
47
 
    access->getline = access_getline;
48
 
    access->destroy = access_destroy;
49
 
 
 
245
    ImagingAccess access = &access_table[hash(im->mode)];
 
246
    if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0)
 
247
        return NULL;
50
248
    return access;
51
249
}
52
250
 
53
251
void
54
 
ImagingAccessDelete(ImagingAccess access)
 
252
_ImagingAccessDelete(Imaging im, ImagingAccess access)
55
253
{
56
 
    if (!access)
57
 
        return;
58
 
 
59
 
    if (access->destroy)
60
 
        access->destroy(access);
61
 
 
62
 
    free(access);
 
254
 
63
255
}