source: branches/common_functions/img_funcs.c@ 173

Last change on this file since 173 was 104, checked in by gyoung, 23 months ago

Remaining changes from merge with Lars 2.9 branch

File size: 16.4 KB
Line 
1/*
2 This file conatins functions for loading image files.
3 */
4
5#define INCL_PM
6#define INCL_OS2MM
7#define INCL_MMIOOS2
8
9#include <os2.h>
10#include "os2me.h"
11#include <string.h> /* for memset() */
12#include <stdlib.h> /* for malloc() */
13#include "sys_funcs.h"
14
15
16/*!**************************************************/
17/* */
18/* @@DESC */
19/* */
20/* This function loads a supported image file. */
21/* Every format for which MMOS2 has an IO procedure */
22/* may be used here. In contrast to */
23/* ImgLoadImageFile() a provided BMPINFOHEADER2 */
24/* structure is filled with data. */
25/* */
26/* */
27/* @@RETURNS */
28/* */
29/* HBITMAP hBitmap */
30/* */
31/* Handle to the bitmap or NULL. */
32/* */
33/* @@PARAM */
34/* */
35/* PSZ pszFileName input */
36/* */
37/* Name of the image file to load. */
38/* */
39/* @@PARAM */
40/* */
41/* PBITMAPINFOHEADER2 pBMPInfoHeader2 in/out */
42/* */
43/* Pointer to a BITMAPINFOHEADER2 structure. */
44/* */
45/* */
46/* @@REMARKS */
47/* */
48/* The caller must free the bitmap handle after */
49/* use. */
50/* */
51/*!!*************************************************/
52HBITMAP ImgLoadImageFileAndHeader( PSZ pszFileName, PBITMAPINFOHEADER2 pBMPInfoHeader2)
53{
54 HBITMAP hbm;
55 MMIOINFO mmioinfo;
56 MMFORMATINFO mmFormatInfo;
57 HMMIO hmmio;
58 ULONG ulImageHeaderLength;
59 MMIMAGEHEADER mmImgHdr;
60 ULONG ulBytesRead;
61 ULONG dwNumRowBytes;
62 PBYTE pRowBuffer;
63 ULONG dwRowCount;
64 SIZEL ImageSize;
65 ULONG dwHeight, dwWidth;
66 FOURCC fccStorageSystem;
67 ULONG dwPadBytes;
68 ULONG dwRowBits;
69 ULONG ulReturnCode;
70 FOURCC fccIOProc;
71 HDC hdc;
72 HPS hps;
73 HAB hab;
74
75 hab=WinQueryAnchorBlock(HWND_DESKTOP);
76
77 ulReturnCode = mmioIdentifyFile ( pszFileName,
78 0L,
79 &mmFormatInfo,
80 &fccStorageSystem,
81 0L,
82 0L);
83 /*
84 * If this file was NOT identified, then this function won't
85 * work, so return an error by indicating an empty bitmap.
86 */
87 if ( ulReturnCode == MMIO_ERROR )
88 {
89 return (0L);
90 }
91 /*
92 * If mmioIdentifyFile did not find a custom-written IO proc which
93 * can understand the image file, then it will return the DOS IO Proc
94 * info because the image file IS a DOS file.
95 */
96 if( mmFormatInfo.fccIOProc == FOURCC_DOS )
97 {
98 return ( 0L );
99 }
100 /*
101 * Ensure this is an IMAGE IOproc, and that it can read
102 * translated data
103 */
104 if ( (mmFormatInfo.ulMediaType != MMIO_MEDIATYPE_IMAGE) ||
105 ((mmFormatInfo.ulFlags & MMIO_CANREADTRANSLATED) == 0) )
106 {
107 return (0L);
108 }
109 else
110 {
111 fccIOProc = mmFormatInfo.fccIOProc;
112 }
113
114 /* Clear out and initialize mminfo structure */
115 memset ( &mmioinfo, 0L, sizeof ( MMIOINFO ) );
116 mmioinfo.fccIOProc = fccIOProc;
117 mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA;
118 hmmio = mmioOpen ( (PSZ) pszFileName,
119 &mmioinfo,
120 MMIO_READ | MMIO_DENYWRITE | MMIO_NOIDENTIFY );
121 if ( ! hmmio )
122 {
123 return (0L);
124 }
125
126
127 ulReturnCode = mmioQueryHeaderLength ( hmmio,
128 (PLONG)&ulImageHeaderLength,
129 0L,
130 0L);
131 if ( ulImageHeaderLength != sizeof ( MMIMAGEHEADER ) )
132 {
133 /* We have a problem.....possibly incompatible versions */
134 ulReturnCode = mmioClose (hmmio, 0L);
135 return (0L);
136 }
137
138 ulReturnCode = mmioGetHeader ( hmmio,
139 &mmImgHdr,
140 (LONG) sizeof ( MMIMAGEHEADER ),
141 (PLONG)&ulBytesRead,
142 0L,
143 0L);
144
145 if ( ulReturnCode != MMIO_SUCCESS )
146 {
147 /* Header unavailable */
148 ulReturnCode = mmioClose (hmmio, 0L);
149 return (0L);
150 }
151
152 /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
153 *pBMPInfoHeader2=mmImgHdr.mmXDIBHeader.BMPInfoHeader2;
154
155 /*
156 * Determine the number of bytes required, per row.
157 * PLANES MUST ALWAYS BE = 1
158 */
159 dwHeight = mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cy;
160 dwWidth = mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cx;
161 dwRowBits = dwWidth * mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cBitCount;
162 dwNumRowBytes = dwRowBits >> 3;
163
164 /*
165 * Account for odd bits used in 1bpp or 4bpp images that are
166 * NOT on byte boundaries.
167 */
168 if ( dwRowBits % 8 )
169 {
170 dwNumRowBytes++;
171 }
172 /*
173 * Ensure the row length in bytes accounts for byte padding.
174 * All bitmap data rows must are aligned on LONG/4-BYTE boundaries.
175 * The data FROM an IOProc should always appear in this form.
176 */
177 dwPadBytes = ( dwNumRowBytes % 4 );
178 if ( dwPadBytes )
179 {
180 dwNumRowBytes += 4 - dwPadBytes;
181 }
182
183 /* Allocate space for ONE row of pels */
184 if ( DosAllocMem( (PPVOID)&pRowBuffer,
185 (ULONG)dwNumRowBytes,
186 fALLOC))
187 {
188 ulReturnCode = mmioClose (hmmio, 0L);
189 return(0L);
190 }
191
192 /* Create a device context */
193 hdc=DevOpenDC(hab, OD_MEMORY,"*",0L, NULL, NULLHANDLE);
194 if(hdc==NULLHANDLE)
195 {
196 DosFreeMem(pRowBuffer);
197 mmioClose (hmmio, 0L);
198 return(0L);
199 }
200
201 /*
202 // ***************************************************
203 // Create a memory presentation space that includes
204 // the memory device context obtained above.
205 // ***************************************************
206 */
207 ImageSize.cx = dwWidth;
208 ImageSize.cy = dwHeight;
209
210 hps = GpiCreatePS ( hab,
211 hdc,
212 &ImageSize,
213 PU_PELS | GPIT_NORMAL | GPIA_ASSOC );
214 if ( !hps )
215 {
216#ifdef DEBUG
217 WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
218 "No HPS...",
219 "Open Image File",
220 (HMODULE) NULL,
221 (ULONG) MB_OK | MB_MOVEABLE |
222 MB_ERROR );
223#endif
224 DevCloseDC(hdc);
225 DosFreeMem(pRowBuffer);
226 mmioClose (hmmio, 0L);
227 return(0L);
228 }
229 /*
230 // GpiSelectPalette(hps, NULLHANDLE);
231 // ***************************************************
232 // Create an uninitialized bitmap. This is where we
233 // will put all of the bits once we read them in.
234 // ***************************************************
235 */
236
237 hbm = GpiCreateBitmap ( hps,
238 &mmImgHdr.mmXDIBHeader.BMPInfoHeader2,
239 0L,
240 NULL,
241 NULL);
242
243 if ( !hbm )
244 {
245#ifdef DEBUG
246 WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
247 "No HBITMAP...",
248 "Open Image File",
249 (HMODULE) NULL,
250 (ULONG) MB_OK | MB_MOVEABLE |
251 MB_ERROR );
252#endif
253 GpiDestroyPS(hps);
254 DevCloseDC(hdc);
255 DosFreeMem(pRowBuffer);
256 ulReturnCode = mmioClose (hmmio, 0L);
257 return(0L);
258 }
259 /****************************************************
260 Select the bitmap into the memory device context.
261 ***************************************************/
262 ulReturnCode = GpiSetBitmap ( hps,
263 hbm );
264 /***************************************************************
265 LOAD THE BITMAP DATA FROM THE FILE
266 One line at a time, starting from the BOTTOM
267 ****************************************************************/
268
269 for ( dwRowCount = 0; dwRowCount < dwHeight; dwRowCount++ )
270 {
271 ulBytesRead = (ULONG) mmioRead ( hmmio,
272 pRowBuffer,
273 dwNumRowBytes );
274 if ( !ulBytesRead )
275 {
276 break;
277 }
278 /*
279 * Allow context switching while previewing.. Couldn't get
280 * it to work. Perhaps will get to it when time is available...
281 */
282 ulReturnCode = GpiSetBitmapBits ( hps,
283 (LONG) dwRowCount,
284 (LONG) 1,
285 (PBYTE) pRowBuffer,
286 (PBITMAPINFO2) &mmImgHdr.mmXDIBHeader.BMPInfoHeader2);
287 }
288
289 /* Clean up */
290 ulReturnCode = GpiSetBitmap ( hps,
291 NULLHANDLE );
292 ulReturnCode = mmioClose (hmmio, 0L);
293 DosFreeMem(pRowBuffer);
294 GpiDestroyPS(hps);
295 DevCloseDC(hdc);
296
297 return(hbm);
298}
299
300
301/*!**************************************************/
302/* */
303/* @@DESC */
304/* */
305/* This function loads a supported image file. */
306/* Every format for which MMOS2 has an IO procedure */
307/* may be used here. */
308/* */
309/* @@PARAM */
310/* */
311/* PSZ pszFileName input */
312/* */
313/* Name of the image file to load. */
314/* */
315/* @@RETURNS */
316/* */
317/* HBITMAP hBitmap */
318/* */
319/* Handle to the bitmap of NULL. */
320/* */
321/*!!*************************************************/
322HBITMAP ImgLoadImageFile ( PSZ pszFileName )
323{
324 BITMAPINFOHEADER2 bmpih2;
325
326 return ImgLoadImageFileAndHeader ( pszFileName, &bmpih2 );
327}
328
329
330
331/*!**************************************************/
332/* */
333/* @@DESC */
334/* */
335/* Build a BITMAPINFOHEADER2 for the given file. */
336/* */
337/* @@PARAM */
338/* */
339/* PSZ pszFileName input */
340/* */
341/* Name of the image file. */
342/* */
343/* @@PARAM */
344/* */
345/* PBITMAPINFOHEADER2 pBMPInfoHeader2 in/out */
346/* */
347/* Pointer to a BITMAPINFOHEADER2 structure. */
348/* */
349/* @@RETURNS */
350/* */
351/* TRUE on success, FALSE otherwise */
352/* */
353/*!!*************************************************/
354BOOL ImgGetBmpInfoHeader(PSZ pszFileName, PBITMAPINFOHEADER2 bmpih2)
355{
356 MMIOINFO mmioinfo;
357 MMFORMATINFO mmFormatInfo;
358 HMMIO hmmio;
359 ULONG ulImageHeaderLength;
360 MMIMAGEHEADER mmImgHdr;
361 FOURCC fccStorageSystem;
362 FOURCC fccIOProc;
363 ULONG ulReturnCode;
364 ULONG ulBytesRead;
365
366 /* Check file size */
367 if(SysQueryFileSize(pszFileName)==0)
368 return FALSE; /* File is empty at the moment, so return without reading. */
369
370 ulReturnCode = mmioIdentifyFile ( pszFileName,
371 0L,
372 &mmFormatInfo,
373 &fccStorageSystem,
374 0L,
375 0L);
376 /*
377 * If this file was NOT identified, then this function won't
378 * work, so return an error by indicating an empty bitmap.
379 */
380 if ( ulReturnCode == MMIO_ERROR )
381 {
382 /* Disabled, because when copying via WPS we end here before the image is available */
383 return (0L);
384 }
385
386 /*
387 * If mmioIdentifyFile did not find a custom-written IO proc which
388 * can understand the image file, then it will return the DOS IO Proc
389 * info because the image file IS a DOS file.
390 */
391 if( mmFormatInfo.fccIOProc == FOURCC_DOS )
392 {
393 return ( 0L );
394 }
395
396 /*
397 * Ensure this is an IMAGE IOproc, and that it can read
398 * translated data
399 */
400 if ( (mmFormatInfo.ulMediaType != MMIO_MEDIATYPE_IMAGE) ||
401 ((mmFormatInfo.ulFlags & MMIO_CANREADTRANSLATED) == 0) )
402 {
403 /* Disabled, because it fails for templates */
404 return (0L);
405 }
406 else
407 {
408 fccIOProc = mmFormatInfo.fccIOProc;
409 }
410#if 0
411 if((pName=malloc(mmFormatInfo.lNameLength+1))!=NULLHANDLE)
412 {
413 LONG lBytesRead;
414 mmioGetFormatName(&mmFormatInfo, pName, &lBytesRead, 0,0);
415 if(procName && ulLength) {
416 strncpy(procName, pName, ulLength-1);
417 procName[ulLength-1]=0;
418 }
419 free(pName);
420 }
421#endif
422
423 /* Clear out and initialize mminfo structure */
424 memset ( &mmioinfo, 0L, sizeof ( MMIOINFO ) );
425 mmioinfo.fccIOProc = fccIOProc;
426 mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA;
427 /*!!!!!!!!!!!!!!!!!!!!!!*/
428
429
430 hmmio = mmioOpen ( (PSZ) pszFileName,
431 &mmioinfo,
432 MMIO_READ | MMIO_DENYWRITE | MMIO_NOIDENTIFY );
433
434 if ( ! hmmio )
435 {
436 // If file could not be opened, return with error
437 return (0L);
438 }
439
440 ulReturnCode = mmioQueryHeaderLength ( hmmio,
441 (PLONG)&ulImageHeaderLength,
442 0L,
443 0L);
444 if ( ulImageHeaderLength != sizeof ( MMIMAGEHEADER ) )
445 {
446 /* We have a problem.....possibly incompatible versions */
447 ulReturnCode = mmioClose (hmmio, 0L);
448 return (0L);
449 }
450
451 ulReturnCode = mmioGetHeader ( hmmio,
452 &mmImgHdr,
453 (LONG) sizeof ( MMIMAGEHEADER ),
454 (PLONG)&ulBytesRead,
455 0L,
456 0L);
457
458 if ( ulReturnCode != MMIO_SUCCESS )
459 {
460 /* Header unavailable */
461 ulReturnCode = mmioClose (hmmio, 0L);
462 return (0L);
463 }
464
465 memcpy(bmpih2, &mmImgHdr.mmXDIBHeader.BMPInfoHeader2,
466 sizeof(BITMAPINFOHEADER2)+256*sizeof(RGB2) );
467 ulReturnCode = mmioClose (hmmio, 0L);
468 return TRUE;
469}
470
471
472
473
Note: See TracBrowser for help on using the repository browser.