source: trunk/src/user32/dib.cpp

Last change on this file was 8097, checked in by sandervl, 23 years ago

PF: fix for 24 bpp bitmaps

File size: 6.7 KB
Line 
1/* $Id: dib.cpp,v 1.9 2002-03-18 13:03:53 sandervl Exp $ */
2
3/*
4 * Win32 DIB functions for OS/2
5 *
6 * Copyright 1999 Sander van Leeuwen (OS/2 Port)
7 *
8 * Based on Wine code (objects\dib.c):
9 *
10 * GDI device-independent bitmaps
11 *
12 * Copyright 1993,1994 Alexandre Julliard
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 *
17 */
18
19#include <os2win.h>
20#include <stdlib.h>
21#include <misc.h>
22#include "dib.h"
23
24#define DBG_LOCALLOG DBG_dib
25#include "dbglocal.h"
26
27/***********************************************************************
28 * DIB_GetDIBWidthBytes
29 *
30 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
31 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
32 */
33int WIN32API DIB_GetDIBWidthBytes( int width, int depth )
34{
35 int words;
36
37 switch(depth)
38 {
39 case 1: words = (width + 31) / 32; break;
40 case 4: words = (width + 7) / 8; break;
41 case 8: words = (width + 3) / 4; break;
42 case 15:
43 case 16: words = (width + 1) / 2; break;
44 case 24: words = (width * 3 + 3)/4; break;
45
46 default:
47 dprintf(("(%d): Unsupported depth\n", depth ));
48 /* fall through */
49 case 32:
50 words = width;
51 }
52 return 4 * words;
53}
54
55/***********************************************************************
56 * DIB_GetDIBImageBytes
57 *
58 * Return the number of bytes used to hold the image in a DIB bitmap.
59 */
60int DIB_GetDIBImageBytes( int width, int height, int depth )
61{
62 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
63}
64
65
66/***********************************************************************
67 * DIB_BitmapInfoSize
68 *
69 * Return the size of the bitmap info structure including color table.
70 */
71int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
72{
73 int colors;
74
75 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
76 {
77 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
78 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
79 return sizeof(BITMAPCOREHEADER) + colors *
80 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
81 }
82 else /* assume BITMAPINFOHEADER */
83 {
84#ifdef __WIN32OS2__
85 /* many windows apps write bitmaps that have 0x1000000 in biClrUsed when
86 in 24 bpp, so I think we can do generic action 24bpp - no clrUsed */
87 colors = 0;
88 if (info->bmiHeader.biBitCount <= 8)
89 {
90#endif
91 colors = info->bmiHeader.biClrUsed;
92 if (!colors)
93 colors = 1 << info->bmiHeader.biBitCount;
94#ifdef __WIN32OS2__
95 }
96#endif
97 return sizeof(BITMAPINFOHEADER) + colors *
98 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
99 }
100}
101
102
103/***********************************************************************
104 * DIB_GetBitmapInfo
105 *
106 * Get the info from a bitmap header.
107 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
108 */
109int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
110 int *height, WORD *bpp, WORD *compr )
111{
112 if (header->biSize == sizeof(BITMAPINFOHEADER))
113 {
114 *width = header->biWidth;
115 *height = header->biHeight;
116 *bpp = header->biBitCount;
117 *compr = header->biCompression;
118 return 1;
119 }
120 if (header->biSize == sizeof(BITMAPCOREHEADER))
121 {
122 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
123 *width = core->bcWidth;
124 *height = core->bcHeight;
125 *bpp = core->bcBitCount;
126 *compr = 0;
127 return 0;
128 }
129 dprintf(("(%ld): wrong size for header\n", header->biSize ));
130 return -1;
131}
132
133/***********************************************************************
134 * DIB_FixColorsToLoadflags
135 *
136 * Change color table entries when LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
137 * are in loadflags
138 */
139void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix)
140{
141 int colors, bitcount;
142 COLORREF c_W, c_S, c_F, c_L, c_C;
143 int incr,i;
144 RGBQUAD *ptr;
145 char *colorptr;
146
147 //SvL: Wine code doesn't work for OS/2 1.3 bitmaps
148 if (bmi->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
149 {
150 if (bmi->bmiHeader.biBitCount > 8) return;
151 colors = bmi->bmiHeader.biClrUsed;
152 bitcount = bmi->bmiHeader.biBitCount;
153 colorptr = (char*)bmi->bmiColors;
154 incr = 4;
155 }
156 else
157 if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
158 {
159 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)bmi;
160
161 if (core->bcBitCount > 8) return;
162 colors = (1 << core->bcBitCount);
163 bitcount = core->bcBitCount;
164 colorptr = (char*)(core + 1);
165 incr = 3;
166 }
167 else
168 {
169 dprintf(("Wrong bitmap header size!\n"));
170 return;
171 }
172
173 if (!colors && (bitcount <= 8))
174 colors = 1 << bitcount;
175
176 c_W = GetSysColor(COLOR_WINDOW);
177 c_S = GetSysColor(COLOR_3DSHADOW);
178 c_F = GetSysColor(COLOR_3DFACE);
179 c_L = GetSysColor(COLOR_3DLIGHT);
180 if (loadflags & LR_LOADTRANSPARENT) {
181 switch (bitcount) {
182 case 1: pix = pix >> 7; break;
183 case 4: pix = pix >> 4; break;
184 case 8: break;
185 default:
186 dprintf(("(%d): Unsupported depth\n", bitcount));
187 return;
188 }
189 if (pix >= colors) {
190 dprintf(("pixel has color index greater than biClrUsed!\n"));
191 return;
192 }
193 if (loadflags & LR_LOADMAP3DCOLORS) c_W = c_F;
194 ptr = (RGBQUAD*)((char*)colorptr+pix*incr);
195
196 ptr->rgbBlue = GetBValue(c_W);
197 ptr->rgbGreen = GetGValue(c_W);
198 ptr->rgbRed = GetRValue(c_W);
199 }
200 if (loadflags & LR_LOADMAP3DCOLORS) {
201 for (i=0; i<colors; i++) {
202 ptr = (RGBQUAD*)(colorptr +i*incr);
203 c_C = RGB(ptr->rgbRed, ptr->rgbGreen, ptr->rgbBlue);
204 if (c_C == RGB(128, 128, 128)) {
205 ptr->rgbRed = GetRValue(c_S);
206 ptr->rgbGreen = GetGValue(c_S);
207 ptr->rgbBlue = GetBValue(c_S);
208 } else if (c_C == RGB(192, 192, 192)) {
209 ptr->rgbRed = GetRValue(c_F);
210 ptr->rgbGreen = GetGValue(c_F);
211 ptr->rgbBlue = GetBValue(c_F);
212 } else if (c_C == RGB(223, 223, 223)) {
213 ptr->rgbRed = GetRValue(c_L);
214 ptr->rgbGreen = GetGValue(c_L);
215 ptr->rgbBlue = GetBValue(c_L);
216 }
217 }
218 }
219
220}
221
222/***********************************************************************
223 * BITMAP_GetWidthBytes
224 *
225 * Return number of bytes taken by a scanline of 16-bit aligned Windows DDB
226 * data.
227 */
228int WIN32API BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
229{
230 switch(bpp)
231 {
232 case 1:
233 return 2 * ((bmWidth+15) >> 4);
234
235 case 24:
236 bmWidth *= 3; /* fall through */
237 case 8:
238 return bmWidth + (bmWidth & 1);
239
240 case 32:
241 return bmWidth * 4;
242
243 case 16:
244 case 15:
245 return bmWidth * 2;
246
247 case 4:
248 return 2 * ((bmWidth+3) >> 2);
249
250 default:
251 dprintf(("BITMAP_GetWidthBytes: Unknown depth %d, please report.\n", bpp ));
252 }
253 return -1;
254}
Note: See TracBrowser for help on using the repository browser.