source: libpipi/trunk/pipi/codec/gdi.c @ 2902

Last change on this file since 2902 was 2902, checked in by Sam Hocevar, 12 years ago

Support C99 types on Win32 through the same hacks as in libcaca.

File size: 4.1 KB
Line 
1/*
2 *  libpipi       Pathetic image processing interface library
3 *  Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id$
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 * gdi.c: Windows GDI I/O functions (BMP only)
17 */
18
19#include "config.h"
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include <windows.h>
26
27#include "pipi.h"
28#include "pipi_internals.h"
29
30pipi_image_t *pipi_load_gdi(const char *name)
31{
32    BITMAPINFO binfo;
33    pipi_image_t *img;
34    pipi_pixels_t *p;
35    uint8_t *data;
36    HBITMAP hbmap;
37    HDC hdc;
38    int x, y;
39
40    hbmap = (HBITMAP)LoadImage(NULL, name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
41    if(!hbmap)
42        return NULL;
43
44    hdc = CreateCompatibleDC(NULL);
45    SelectObject(hdc, hbmap);
46
47    memset(&binfo, 0, sizeof(binfo));
48    binfo.bmiHeader.biSize = sizeof(binfo.bmiHeader);
49    if(!GetDIBits(hdc, hbmap, 0, 0, 0, &binfo, DIB_RGB_COLORS))
50    {
51        ReleaseDC(0, hdc);
52        DeleteObject(hbmap);
53        return NULL;
54    }
55
56    img = pipi_new(binfo.bmiHeader.biWidth, binfo.bmiHeader.biHeight);
57    p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
58    data = p->pixels;
59
60    binfo.bmiHeader.biBitCount = 32;
61    binfo.bmiHeader.biCompression = BI_RGB;
62    binfo.bmiHeader.biHeight = - abs(binfo.bmiHeader.biHeight);
63    if(!GetDIBits(hdc, hbmap, 0, binfo.bmiHeader.biHeight, data,
64                  &binfo, DIB_RGB_COLORS))
65    {
66        ReleaseDC(0, hdc);
67        DeleteObject(hbmap);
68        return NULL;
69    }
70
71    /* FIXME: get rid of this loop, maybe by using BITMAPV4HEADER above
72     * so that GDI reorders the pixels for us. */
73    for(y = 0; y < img->h; y++)
74        for(x = 0; x < img->w; x++)
75        {
76            /* Swap B and R, don't touch G and A. */
77            uint8_t tmp = data[0]; data[0] = data[2]; data[2] = tmp;
78            data += 4;
79        }
80
81    img->codec_priv = NULL;
82
83    img->wrap = 0;
84    img->u8 = 1;
85
86    ReleaseDC(0, hdc);
87    DeleteObject(hbmap);
88
89    return img;
90}
91
92int pipi_save_gdi(pipi_image_t *img, const char *name)
93{
94    BITMAPINFOHEADER binfo;
95    BITMAPFILEHEADER bfheader;
96    uint8_t dummy[4] = { 0 };
97    HANDLE hfile;
98    pipi_pixels_t *p;
99    DWORD ret = 0;
100    uint8_t *data;
101    int x, y, padding;
102
103    p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
104    data = p->pixels;
105
106    padding = ((img->w * 3) + 3) / 4 * 4 - img->w * 3;
107
108    memset(&binfo, 0, sizeof(binfo));
109    binfo.biSize = sizeof(binfo);
110    binfo.biWidth = img->w;
111    binfo.biHeight = img->h;
112    binfo.biPlanes = 1;
113    binfo.biBitCount = 24;
114    binfo.biCompression = BI_RGB;
115    binfo.biSizeImage = (img->w * 3 + padding) * img->h;
116
117    memset(&bfheader, 0, sizeof(bfheader));
118    bfheader.bfType = 0x4D42;
119    bfheader.bfOffBits = sizeof(bfheader) + sizeof(binfo);
120    bfheader.bfSize = bfheader.bfOffBits + binfo.biSizeImage;
121
122    /* We don’t even create the bitmap object, since we know exactly
123     * what kind of file we are saving. But later, when we support
124     * different depths and BMP options, we'll need to care about it. */
125    hfile = CreateFile(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
126                       FILE_ATTRIBUTE_ARCHIVE, NULL);
127    if(!hfile)
128        return -1;
129    WriteFile(hfile, &bfheader, sizeof(bfheader), &ret, NULL);
130    WriteFile(hfile, &binfo, sizeof(binfo), &ret, NULL);
131    for(y = 0; y < img->h; y++)
132    {
133        for(x = 0; x < img->w; x++)
134        {
135            uint8_t tmp[3];
136            tmp[0] = data[4 * (img->w * (img->h - 1 - y) + x) + 2];
137            tmp[1] = data[4 * (img->w * (img->h - 1 - y) + x) + 1];
138            tmp[2] = data[4 * (img->w * (img->h - 1 - y) + x) + 0];
139            WriteFile(hfile, tmp, 3, &ret, NULL);
140        }
141        if(padding)
142            WriteFile(hfile, dummy, padding, &ret, NULL);
143    }
144    CloseHandle(hfile);
145
146    return 0;
147}
148
149/*
150 * XXX: The following functions are local.
151 */
152
Note: See TracBrowser for help on using the repository browser.