Pillow

Форк
0
317 строк · 8.2 Кб
1
/*
2
 * The Python Imaging Library
3
 * $Id$
4
 *
5
 * imaging display object for Windows
6
 *
7
 * history:
8
 * 1996-05-12 fl  Created
9
 * 1996-05-17 fl  Up and running
10
 * 1996-05-21 fl  Added palette stuff
11
 * 1996-05-26 fl  Added query palette and mode inquery
12
 * 1997-09-21 fl  Added draw primitive
13
 * 1998-01-20 fl  Use StretchDIBits instead of StretchBlt
14
 * 1998-12-30 fl  Plugged a resource leak in DeleteDIB (from Roger Burnham)
15
 *
16
 * Copyright (c) Secret Labs AB 1997-2001.
17
 * Copyright (c) Fredrik Lundh 1996.
18
 *
19
 * See the README file for information on usage and redistribution.
20
 */
21

22
#include "Imaging.h"
23

24
#ifdef _WIN32
25

26
#include "ImDib.h"
27

28
char *
29
ImagingGetModeDIB(int size_out[2]) {
30
    /* Get device characteristics */
31

32
    HDC dc;
33
    char *mode;
34

35
    dc = CreateCompatibleDC(NULL);
36

37
    mode = "P";
38
    if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) {
39
        mode = "RGB";
40
        if (GetDeviceCaps(dc, BITSPIXEL) == 1) {
41
            mode = "1";
42
        }
43
    }
44

45
    if (size_out) {
46
        size_out[0] = GetDeviceCaps(dc, HORZRES);
47
        size_out[1] = GetDeviceCaps(dc, VERTRES);
48
    }
49

50
    DeleteDC(dc);
51

52
    return mode;
53
}
54

55
ImagingDIB
56
ImagingNewDIB(const char *mode, int xsize, int ysize) {
57
    /* Create a Windows bitmap */
58

59
    ImagingDIB dib;
60
    RGBQUAD *palette;
61
    int i;
62

63
    /* Check mode */
64
    if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 && strcmp(mode, "RGB") != 0) {
65
        return (ImagingDIB)ImagingError_ModeError();
66
    }
67

68
    /* Create DIB context and info header */
69
    /* malloc check ok, small constant allocation */
70
    dib = (ImagingDIB)malloc(sizeof(*dib));
71
    if (!dib) {
72
        return (ImagingDIB)ImagingError_MemoryError();
73
    }
74
    /* malloc check ok, small constant allocation */
75
    dib->info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
76
    if (!dib->info) {
77
        free(dib);
78
        return (ImagingDIB)ImagingError_MemoryError();
79
    }
80

81
    memset(dib->info, 0, sizeof(BITMAPINFOHEADER));
82
    dib->info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
83
    dib->info->bmiHeader.biWidth = xsize;
84
    dib->info->bmiHeader.biHeight = ysize;
85
    dib->info->bmiHeader.biPlanes = 1;
86
    dib->info->bmiHeader.biBitCount = strlen(mode) * 8;
87
    dib->info->bmiHeader.biCompression = BI_RGB;
88

89
    /* Create DIB */
90
    dib->dc = CreateCompatibleDC(NULL);
91
    if (!dib->dc) {
92
        free(dib->info);
93
        free(dib);
94
        return (ImagingDIB)ImagingError_MemoryError();
95
    }
96

97
    dib->bitmap = CreateDIBSection(
98
        dib->dc, dib->info, DIB_RGB_COLORS, (void **)&dib->bits, NULL, 0
99
    );
100
    if (!dib->bitmap) {
101
        free(dib->info);
102
        free(dib);
103
        return (ImagingDIB)ImagingError_MemoryError();
104
    }
105

106
    strcpy(dib->mode, mode);
107
    dib->xsize = xsize;
108
    dib->ysize = ysize;
109

110
    dib->pixelsize = strlen(mode);
111
    dib->linesize = (xsize * dib->pixelsize + 3) & -4;
112

113
    if (dib->pixelsize == 1) {
114
        dib->pack = dib->unpack = (ImagingShuffler)memcpy;
115
    } else {
116
        dib->pack = ImagingPackBGR;
117
        dib->unpack = ImagingPackBGR;
118
    }
119

120
    /* Bind the DIB to the device context */
121
    dib->old_bitmap = SelectObject(dib->dc, dib->bitmap);
122

123
    palette = dib->info->bmiColors;
124

125
    /* Bind a palette to it as well (only required for 8-bit DIBs) */
126
    if (dib->pixelsize == 1) {
127
        for (i = 0; i < 256; i++) {
128
            palette[i].rgbRed = palette[i].rgbGreen = palette[i].rgbBlue = i;
129
            palette[i].rgbReserved = 0;
130
        }
131
        SetDIBColorTable(dib->dc, 0, 256, palette);
132
    }
133

134
    /* Create an associated palette (for 8-bit displays only) */
135
    if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) {
136
        char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
137
        LPLOGPALETTE pal = (LPLOGPALETTE)palbuf;
138
        int i, r, g, b;
139

140
        /* Load system palette */
141
        pal->palVersion = 0x300;
142
        pal->palNumEntries = 256;
143
        GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry);
144

145
        if (strcmp(mode, "L") == 0) {
146
            /* Grayscale DIB.  Fill all 236 slots with a grayscale ramp
147
             * (this is usually overkill on Windows since VGA only offers
148
             * 6 bits grayscale resolution).  Ignore the slots already
149
             * allocated by Windows */
150

151
            i = 10;
152
            for (r = 0; r < 236; r++) {
153
                pal->palPalEntry[i].peRed = pal->palPalEntry[i].peGreen =
154
                    pal->palPalEntry[i].peBlue = i;
155
                i++;
156
            }
157

158
            dib->palette = CreatePalette(pal);
159

160
        } else if (strcmp(mode, "RGB") == 0) {
161
#ifdef CUBE216
162

163
            /* Colour DIB.  Create a 6x6x6 colour cube (216 entries) and
164
             * add 20 extra graylevels for best result with grayscale
165
             * images. */
166

167
            i = 10;
168
            for (r = 0; r < 256; r += 51) {
169
                for (g = 0; g < 256; g += 51) {
170
                    for (b = 0; b < 256; b += 51) {
171
                        pal->palPalEntry[i].peRed = r;
172
                        pal->palPalEntry[i].peGreen = g;
173
                        pal->palPalEntry[i].peBlue = b;
174
                        i++;
175
                    }
176
                }
177
            }
178
            for (r = 1; r < 22 - 1; r++) {
179
                /* Black and white are already provided by the cube. */
180
                pal->palPalEntry[i].peRed = pal->palPalEntry[i].peGreen =
181
                    pal->palPalEntry[i].peBlue = r * 255 / (22 - 1);
182
                i++;
183
            }
184

185
#else
186

187
            /* Colour DIB.  Alternate palette. */
188

189
            i = 10;
190
            for (r = 0; r < 256; r += 37) {
191
                for (g = 0; g < 256; g += 32) {
192
                    for (b = 0; b < 256; b += 64) {
193
                        pal->palPalEntry[i].peRed = r;
194
                        pal->palPalEntry[i].peGreen = g;
195
                        pal->palPalEntry[i].peBlue = b;
196
                        i++;
197
                    }
198
                }
199
            }
200

201
#endif
202

203
            dib->palette = CreatePalette(pal);
204
        }
205
    }
206

207
    return dib;
208
}
209

210
void
211
ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]) {
212
    /* Paste image data into a bitmap */
213

214
    /* FIXME: check size! */
215

216
    int y;
217
    for (y = 0; y < im->ysize; y++) {
218
        dib->pack(
219
            dib->bits + dib->linesize * (dib->ysize - (xy[1] + y) - 1) +
220
                xy[0] * dib->pixelsize,
221
            im->image[y],
222
            im->xsize
223
        );
224
    }
225
}
226

227
void
228
ImagingExposeDIB(ImagingDIB dib, void *dc) {
229
    /* Copy bitmap to display */
230

231
    if (dib->palette != 0) {
232
        SelectPalette((HDC)dc, dib->palette, FALSE);
233
    }
234
    BitBlt((HDC)dc, 0, 0, dib->xsize, dib->ysize, dib->dc, 0, 0, SRCCOPY);
235
}
236

237
void
238
ImagingDrawDIB(ImagingDIB dib, void *dc, int dst[4], int src[4]) {
239
    /* Copy bitmap to printer/display */
240

241
    if (GetDeviceCaps((HDC)dc, RASTERCAPS) & RC_STRETCHDIB) {
242
        /* stretchdib (printers) */
243
        StretchDIBits(
244
            (HDC)dc,
245
            dst[0],
246
            dst[1],
247
            dst[2] - dst[0],
248
            dst[3] - dst[1],
249
            src[0],
250
            src[1],
251
            src[2] - src[0],
252
            src[3] - src[1],
253
            dib->bits,
254
            dib->info,
255
            DIB_RGB_COLORS,
256
            SRCCOPY
257
        );
258
    } else {
259
        /* stretchblt (displays) */
260
        if (dib->palette != 0) {
261
            SelectPalette((HDC)dc, dib->palette, FALSE);
262
        }
263
        StretchBlt(
264
            (HDC)dc,
265
            dst[0],
266
            dst[1],
267
            dst[2] - dst[0],
268
            dst[3] - dst[1],
269
            dib->dc,
270
            src[0],
271
            src[1],
272
            src[2] - src[0],
273
            src[3] - src[1],
274
            SRCCOPY
275
        );
276
    }
277
}
278

279
int
280
ImagingQueryPaletteDIB(ImagingDIB dib, void *dc) {
281
    /* Install bitmap palette */
282

283
    int n;
284

285
    if (dib->palette != 0) {
286
        /* Realize associated palette */
287
        HPALETTE now = SelectPalette((HDC)dc, dib->palette, FALSE);
288
        n = RealizePalette((HDC)dc);
289

290
        /* Restore palette */
291
        SelectPalette((HDC)dc, now, FALSE);
292

293
    } else {
294
        n = 0;
295
    }
296

297
    return n; /* number of colours that was changed */
298
}
299

300
void
301
ImagingDeleteDIB(ImagingDIB dib) {
302
    /* Clean up */
303

304
    if (dib->palette) {
305
        DeleteObject(dib->palette);
306
    }
307
    if (dib->bitmap) {
308
        SelectObject(dib->dc, dib->old_bitmap);
309
        DeleteObject(dib->bitmap);
310
    }
311
    if (dib->dc) {
312
        DeleteDC(dib->dc);
313
    }
314
    free(dib->info);
315
}
316

317
#endif /* _WIN32 */
318

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

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

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

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