source: trunk/common_functions/img_funcs.c@ 70

Last change on this file since 70 was 4, checked in by stevenhl, 8 years ago

Import modifications from cwmm-0_2_9-work-01_10_2006.zip dated 2006-08-27

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