소스 검색

gdi.c: the GDI codec can now open and save BMP files.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2840 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 년 전
부모
커밋
9f10fdd2b9
4개의 변경된 파일167개의 추가작업 그리고 0개의 파일을 삭제
  1. +1
    -0
      pipi/Makefile.am
  2. +8
    -0
      pipi/codec.c
  3. +153
    -0
      pipi/codec/gdi.c
  4. +5
    -0
      pipi/pipi_internals.h

+ 1
- 0
pipi/Makefile.am 파일 보기

@@ -103,6 +103,7 @@ codec_sources += codec/opencv.c
endif

if USE_GDI
codec_libs += -lgdi32
codec_sources += codec/gdi.c
endif


+ 8
- 0
pipi/codec.c 파일 보기

@@ -48,6 +48,10 @@ pipi_image_t *pipi_load(char const *name)
if(!ret)
ret = pipi_load_sdl(name);
#endif
#if USE_GDI
if(!ret)
ret = pipi_load_gdi(name);
#endif

return ret;
}
@@ -82,6 +86,10 @@ int pipi_save(pipi_image_t *img, const char *name)
if(ret < 0)
ret = pipi_save_sdl(img, name);
#endif
#if USE_GDI
if(ret < 0)
ret = pipi_save_gdi(img, name);
#endif

return ret;
}


+ 153
- 0
pipi/codec/gdi.c 파일 보기

@@ -0,0 +1,153 @@
/*
* libpipi Proper image processing implementation library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This library is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* gdi.c: Windows GDI I/O functions (BMP only)
*/

#include "config.h"
#include "common.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <windows.h>

#include "pipi.h"
#include "pipi_internals.h"

pipi_image_t *pipi_load_gdi(const char *name)
{
BITMAPINFO binfo;
pipi_image_t *img;
pipi_pixels_t *p;
uint8_t *data;
HBITMAP hbmap;
HDC hdc;
int x, y;

hbmap = (HBITMAP)LoadImage(NULL, name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(!hbmap)
return NULL;

hdc = CreateCompatibleDC(NULL);
SelectObject(hdc, hbmap);

memset(&binfo, 0, sizeof(binfo));
binfo.bmiHeader.biSize = sizeof(binfo.bmiHeader);
if(!GetDIBits(hdc, hbmap, 0, 0, 0, &binfo, DIB_RGB_COLORS))
{
ReleaseDC(0, hdc);
DeleteObject(hbmap);
return NULL;
}

img = pipi_new(binfo.bmiHeader.biWidth, binfo.bmiHeader.biHeight);
p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
data = p->pixels;

binfo.bmiHeader.biBitCount = 32;
binfo.bmiHeader.biCompression = BI_RGB;
binfo.bmiHeader.biHeight = - abs(binfo.bmiHeader.biHeight);
if(!GetDIBits(hdc, hbmap, 0, binfo.bmiHeader.biHeight, data,
&binfo, DIB_RGB_COLORS))
{
ReleaseDC(0, hdc);
DeleteObject(hbmap);
return NULL;
}

/* FIXME: get rid of this loop, maybe by using BITMAPV4HEADER above
* so that GDI reorders the pixels for us. */
for(y = 0; y < img->h; y++)
for(x = 0; x < img->w; x++)
{
/* Swap B and R, don't touch G and A. */
uint8_t tmp = data[0]; data[0] = data[2]; data[2] = tmp;
data += 4;
}

img->codec_priv = NULL;

img->wrap = 0;
img->u8 = 1;

ReleaseDC(0, hdc);
DeleteObject(hbmap);

return img;
}

int pipi_save_gdi(pipi_image_t *img, const char *name)
{
BITMAPINFOHEADER binfo;
BITMAPFILEHEADER bfheader;
uint8_t dummy[4] = { 0 };
HANDLE hfile;
pipi_pixels_t *p;
DWORD ret = 0;
uint8_t *data;
int x, y, padding;

p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
data = p->pixels;

padding = ((img->w * 3) + 3) / 4 * 4 - img->w * 3;

memset(&binfo, 0, sizeof(binfo));
binfo.biSize = sizeof(binfo);
binfo.biWidth = img->w;
binfo.biHeight = img->h;
binfo.biPlanes = 1;
binfo.biBitCount = 24;
binfo.biCompression = BI_RGB;
binfo.biSizeImage = (img->w * 3 + padding) * img->h;

memset(&bfheader, 0, sizeof(bfheader));
bfheader.bfType = 0x4D42;
bfheader.bfOffBits = sizeof(bfheader) + sizeof(binfo);
bfheader.bfSize = bfheader.bfOffBits + binfo.biSizeImage;

/* We don’t even create the bitmap object, since we know exactly
* what kind of file we are saving. But later, when we support
* different depths and BMP options, we'll need to care about it. */
hfile = CreateFile(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_ARCHIVE, NULL);
if(!hfile)
return -1;
WriteFile(hfile, &bfheader, sizeof(bfheader), &ret, NULL);
WriteFile(hfile, &binfo, sizeof(binfo), &ret, NULL);
for(y = 0; y < img->h; y++)
{
for(x = 0; x < img->w; x++)
{
uint8_t tmp[3];
tmp[0] = data[4 * (img->w * (img->h - 1 - y) + x) + 2];
tmp[1] = data[4 * (img->w * (img->h - 1 - y) + x) + 1];
tmp[2] = data[4 * (img->w * (img->h - 1 - y) + x) + 0];
WriteFile(hfile, tmp, 3, &ret, NULL);
}
if(padding)
WriteFile(hfile, dummy, padding, &ret, NULL);
}
CloseHandle(hfile);

return 0;
}

/*
* XXX: The following functions are local.
*/


+ 5
- 0
pipi/pipi_internals.h 파일 보기

@@ -80,5 +80,10 @@ pipi_image_t *pipi_load_sdl(const char *name);
int pipi_save_sdl(pipi_image_t *img, const char *name);
#endif

#ifdef USE_GDI
pipi_image_t *pipi_load_gdi(const char *name);
int pipi_save_gdi(pipi_image_t *img, const char *name);
#endif

#endif /* __PIPI_INTERNALS_H__ */


불러오는 중...
취소
저장