source: trunk/src/helpers/mmpmh.c

Last change on this file was 303, checked in by pr, 20 years ago

Fix warnings

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1
2/*
3 *@@sourcefile mmpmh.c:
4 *
5 * Usage: OS/2 PM programs.
6 *
7 * Function prefixes (new with V0.81):
8 * -- mmh*
9 *
10 * This file is new with V1.0.1 and contains some
11 * code formerly in XWorkplace multimedia.
12 *
13 * Note: Version numbering in this file relates to XWorkplace version
14 * numbering.
15 *
16 *@@header "helpers\mmpmh.h"
17 *@@added V1.0.1 (2003-01-25) [umoeller]
18 */
19
20/*
21 * Copyright (C) 1997-2005 Ulrich M”ller.
22 * This file is part of the "XWorkplace helpers" source package.
23 * This is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published
25 * by the Free Software Foundation, in version 2 as it comes in the
26 * "COPYING" file of the XWorkplace main distribution.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 */
32
33#define INCL_DOSEXCEPTIONS
34#define INCL_DOSPROCESS
35#define INCL_DOSERRORS
36
37#define INCL_GPI // required for INCL_MMIO_CODEC
38#define INCL_GPIBITMAPS // required for INCL_MMIO_CODEC
39#include <os2.h>
40
41#define INCL_MCIOS2
42#define INCL_MMIOOS2
43#define INCL_MMIO_CODEC
44#include <os2me.h>
45
46#include <stdio.h>
47#include <setjmp.h>
48
49#include "setup.h" // code generation and debugging options
50
51#include "helpers\dosh.h"
52#include "helpers\except.h"
53#include "helpers\gpih.h"
54#include "helpers\mmpmh.h"
55#include "helpers\standards.h"
56
57#pragma hdrstop
58
59/*
60 *@@category: Helpers\Multimedia helpers
61 * See nls.c.
62 */
63
64/* ******************************************************************
65 *
66 * Global variables
67 *
68 ********************************************************************/
69
70extern FNTD_MCISENDCOMMAND *G_mciSendCommand = NULL;
71extern FNTD_MCIGETERRORSTRING *G_mciGetErrorString = NULL;
72
73extern FNTD_MMIOINIFILECODEC *G_mmioIniFileCODEC = NULL;
74extern FNTD_MMIOQUERYCODECNAMELENGTH *G_mmioQueryCODECNameLength = NULL;
75extern FNTD_MMIOQUERYCODECNAME *G_mmioQueryCODECName = NULL;
76extern FNTD_MMIOINIFILEHANDLER *G_mmioIniFileHandler = NULL;
77extern FNTD_MMIOQUERYFORMATCOUNT *G_mmioQueryFormatCount = NULL;
78extern FNTD_MMIOGETFORMATS *G_mmioGetFormats = NULL;
79extern FNTD_MMIOGETFORMATNAME *G_mmioGetFormatName = NULL;
80
81extern FNTD_MMIOGETHEADER *G_mmioGetHeader = NULL;
82extern FNTD_MMIOREAD *G_mmioRead = NULL;
83extern FNTD_MMIOIDENTIFYFILE *G_mmioIdentifyFile = NULL;
84extern FNTD_MMIOOPEN *G_mmioOpen = NULL;
85extern FNTD_MMIOQUERYHEADERLENGTH *G_mmioQueryHeaderLength = NULL;
86extern FNTD_MMIOCLOSE *G_mmioClose = NULL;
87
88BOOL G_fFuncsResolved = FALSE;
89
90/*
91 * G_aResolveFromMDM:
92 * functions imported from MDM.DLL.
93 * Used with doshResolveImports.
94 */
95
96static const RESOLVEFUNCTION G_aResolveFromMDM[] =
97 {
98 "mciSendCommand", (PFN*)&G_mciSendCommand,
99 "mciGetErrorString", (PFN*)&G_mciGetErrorString
100 };
101
102/*
103 * G_aResolveFromMMIO:
104 * functions resolved from MMIO.DLL.
105 * Used with doshResolveImports.
106 */
107
108static const RESOLVEFUNCTION G_aResolveFromMMIO[] =
109 {
110 "mmioIniFileCODEC", (PFN*)&G_mmioIniFileCODEC,
111 "mmioQueryCODECNameLength", (PFN*)&G_mmioQueryCODECNameLength,
112 "mmioQueryCODECName", (PFN*)&G_mmioQueryCODECName,
113 "mmioIniFileHandler", (PFN*)&G_mmioIniFileHandler,
114 "mmioQueryFormatCount", (PFN*)&G_mmioQueryFormatCount,
115 "mmioGetFormats", (PFN*)&G_mmioGetFormats,
116 "mmioGetFormatName", (PFN*)&G_mmioGetFormatName,
117 "mmioGetHeader", (PFN*)&G_mmioGetHeader,
118 "mmioRead", (PFN*)&G_mmioRead,
119 "mmioIdentifyFile", (PFN*)&G_mmioIdentifyFile,
120 "mmioOpen", (PFN*)&G_mmioOpen,
121 "mmioQueryHeaderLength", (PFN*)&G_mmioQueryHeaderLength,
122 "mmioClose", (PFN*)&G_mmioClose,
123 };
124
125/* ******************************************************************
126 *
127 * Initialization
128 *
129 ********************************************************************/
130
131/*
132 *@@ mmhInit:
133 * initializes the MMPM helpers by resolving
134 * some MMPM/2 functions dynamically from the
135 * MDM.DLL and MMIO.DLL libraries.
136 */
137
138APIRET mmhInit(VOID)
139{
140 APIRET arc;
141
142 HMODULE hmodMDM = NULLHANDLE,
143 hmodMMIO = NULLHANDLE;
144
145 if (!(arc = doshResolveImports("MDM.DLL",
146 &hmodMDM,
147 G_aResolveFromMDM,
148 ARRAYITEMCOUNT(G_aResolveFromMDM))))
149 if (!(arc = doshResolveImports("MMIO.DLL",
150 &hmodMMIO,
151 G_aResolveFromMMIO,
152 ARRAYITEMCOUNT(G_aResolveFromMMIO))))
153 G_fFuncsResolved = TRUE;
154
155 return arc;
156}
157
158/* ******************************************************************
159 *
160 * IOProcs info
161 *
162 ********************************************************************/
163
164/*
165 *@@ mmhGetIOProcs:
166 * allocates and fills an array of MMFORMATINFO
167 * structures describing the IOProcs that are
168 * installed on the system.
169 *
170 * On input, specify any combination of these
171 * flags to filter the type of IOProcs returned:
172 *
173 * -- MMIO_MEDIATYPE_AUDIO (0x00000002)
174 *
175 * -- MMIO_MEDIATYPE_IMAGE (0x00000001)
176 *
177 * -- MMIO_MEDIATYPE_DIGITALVIDEO (0x00000040)
178 *
179 * -- MMIO_MEDIATYPE_MIDI (0x00000004)
180 *
181 * -- MMIO_MEDIATYPE_MOVIE (0x00000100)
182 *
183 * -- MMIO_MEDIATYPE_ANIMATION (0x00000080)
184 *
185 * -- MMIO_MEDIATYPE_COMPOUND (0x00000008)
186 *
187 * -- MMIO_MEDIATYPE_OTHER (0x00000010)
188 *
189 * -- MMIO_MEDIATYPE_UNKNOWN (0x00000020)
190 *
191 * If none of these are specified, all known formats
192 * are returned.
193 *
194 * If NO_ERROR is returned, *ppaInfos has been
195 * set to a newly allocated array, which the caller
196 * must free().
197 *
198 * Otherwise this returns one of the following
199 * error codes:
200 *
201 * -- ERROR_NOT_ENOUGH_MEMORY
202 *
203 * -- MMIOERR_INVALID_PARAMETER
204 *
205 * -- MMIOERR_INTERNAL_SYSTEM
206 *
207 * -- MMIO_ERROR: something else went wrong.
208 */
209
210APIRET mmhGetIOProcs(ULONG flMediaType, // in: MMIO_MEDIATYPE_* flags
211 PMMFORMATINFO *ppaInfos, // out: new array of formats
212 PLONG pcFormats) // out: no. of items in array (not array size!)
213{
214 APIRET arc;
215 MMFORMATINFO mmfi;
216 LONG cFormats;
217
218 if (!G_fFuncsResolved)
219 return MMHERR_MMPM_NOT_INITIALIZED;
220
221 memset(&mmfi, 0, sizeof(mmfi)); // zeroed struct means get all
222 mmfi.ulMediaType = flMediaType;
223 mmfi.ulStructLen = sizeof(mmfi);
224
225 if (!(arc = G_mmioQueryFormatCount(&mmfi,
226 &cFormats,
227 0, // "reserved"
228 0))) // "reserved"
229 {
230 PMMFORMATINFO pammfi;
231 if (!(pammfi = (PMMFORMATINFO)malloc(cFormats * sizeof(MMFORMATINFO))))
232 arc = ERROR_NOT_ENOUGH_MEMORY;
233 else
234 {
235 LONG lFormatsRead = 0;
236 if (!(arc = G_mmioGetFormats(&mmfi,
237 cFormats,
238 pammfi,
239 pcFormats,
240 0, // reserved
241 0))) // reserved
242 *ppaInfos = pammfi;
243 else
244 free(pammfi);
245 }
246 }
247
248 return arc;
249}
250
251/* ******************************************************************
252 *
253 * File identification
254 *
255 ********************************************************************/
256
257/*
258 *@@ mmhIdentifyFile:
259 * attempts to find an IOProc that can read the specified
260 * file.
261 *
262 * If NO_ERROR is returned, this fills the given MMFORMATINFO
263 * with data about the given file.
264 *
265 * Otherwise this returns:
266 *
267 * -- MMHERR_MMPM_NOT_INITIALIZED: mmhInit not called or
268 * it failed.
269 *
270 * -- MMHERR_NO_IOPROC: no IOProc is installed
271 * to handle this format.
272 */
273
274APIRET mmhIdentifyFile(PCSZ pcszFilename, // in: file to check
275 PMMFORMATINFO pmmfi) // out: file format info
276{
277 APIRET arc;
278 FOURCC fccStorageSystem;
279
280 if (!G_fFuncsResolved)
281 return MMHERR_MMPM_NOT_INITIALIZED;
282
283 if (!(arc = G_mmioIdentifyFile(pcszFilename,
284 NULL, // needed for RIFF only
285 pmmfi, // out: format info (FOURCC)
286 &fccStorageSystem, // out: FOURCC of storage IOProc
287 0L, // reserved
288 0L))) // can be:
289 /* MMIO_FORCE_IDENTIFY_SS
290 Forces the identification of a storage
291 system by ignoring the file
292 name and actually checking the MMIO Manager's
293 I/O procedure list.
294 MMIO_FORCE_IDENTIFY_FF
295 Forces the identification of a file
296 format by ignoring the file name
297 and actually checking the MMIO Manager's
298 I/O procedure list. */
299 {
300 // if mmioIdentifyFile did not find a custom-written IO proc which
301 // can understand the image file, then it will return the DOS IO Proc
302 // info because the image file IS a DOS file.
303 if ( (pmmfi->fccIOProc == FOURCC_DOS)
304 || (!(pmmfi->ulFlags & MMIO_CANREADTRANSLATED))
305 )
306 arc = MMHERR_NO_IOPROC;
307 }
308
309 return arc;
310}
311
312/* ******************************************************************
313 *
314 * Image loading
315 *
316 ********************************************************************/
317
318/*
319 *@@ mmhOpenImage:
320 *
321 */
322
323APIRET mmhOpenImage(PCSZ pcszFilename, // in: filename to load
324 FOURCC fccIOProc, // in: FOURCC of ioproc to use; if 0, we call mmhIdentifyFile here
325 HMMIO *phmmio) // out: mmio handle
326{
327 APIRET arc = NO_ERROR;
328
329 if ( (!pcszFilename)
330 || (!phmmio)
331 )
332 return ERROR_INVALID_PARAMETER;
333
334 if (!G_fFuncsResolved)
335 return MMHERR_MMPM_NOT_INITIALIZED;
336
337#ifdef __DEBUG__
338 TRY_LOUD(excpt1)
339#else
340 TRY_QUIET(excpt1)
341#endif
342 {
343 if (!fccIOProc)
344 {
345 MMFORMATINFO mmfi;
346 if (!(arc = mmhIdentifyFile(pcszFilename, &mmfi)))
347 // ensure this is an IMAGE IOproc
348 if (mmfi.ulMediaType != MMIO_MEDIATYPE_IMAGE)
349 arc = MMHERR_NOT_IMAGE_FILE;
350 else
351 fccIOProc = mmfi.fccIOProc;
352 }
353
354 if (!arc)
355 {
356 MMIOINFO mmioinfo;
357
358 memset(&mmioinfo, 0, sizeof(MMIOINFO));
359 mmioinfo.fccIOProc = fccIOProc;
360 mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA;
361
362 if (!(*phmmio = G_mmioOpen(pcszFilename,
363 &mmioinfo,
364 MMIO_READ | MMIO_DENYWRITE | MMIO_NOIDENTIFY)))
365 arc = MMHERR_OPEN_FAILED;
366 }
367 }
368 CATCH(excpt1)
369 {
370 arc = ERROR_PROTECTION_VIOLATION;
371 } END_CATCH();
372
373 return arc;
374}
375
376/*
377 *@@ mmhLoadImageHeader:
378 *
379 */
380
381APIRET mmhLoadImageHeader(HMMIO hmmio, // in: mmio handle from mmhOpenImage
382 PMMIMAGEHEADER pmmih, // out: mmio image header
383 PULONG pcbBytesPerRow) // out: padded bytes for each bitmap scan line
384{
385 APIRET arc = NO_ERROR;
386
387 if ( (!hmmio)
388 || (!pmmih)
389 || (!pcbBytesPerRow)
390 )
391 return ERROR_INVALID_PARAMETER;
392
393 if (!G_fFuncsResolved)
394 return MMHERR_MMPM_NOT_INITIALIZED;
395
396#ifdef __DEBUG__
397 TRY_LOUD(excpt1)
398#else
399 TRY_QUIET(excpt1)
400#endif
401 {
402 ULONG cbHeader;
403 LONG lBytesRead;
404 if ( (G_mmioQueryHeaderLength(hmmio,
405 (PLONG)&cbHeader,
406 0L,
407 0L))
408 || (cbHeader != sizeof (MMIMAGEHEADER))
409 || (G_mmioGetHeader(hmmio,
410 pmmih,
411 sizeof(MMIMAGEHEADER),
412 &lBytesRead,
413 0,
414 0))
415 )
416 arc = MMHERR_INCOMPATIBLE_HEADER;
417 else
418 {
419 /*
420 * Determine the number of bytes required, per row.
421 * PLANES MUST ALWAYS BE = 1
422 */
423
424 ULONG cRowBits;
425 // ULONG cbBytesPerRow;
426
427 ULONG cbPadding;
428
429 // szlSourceBmp.cx = mmih.mmXDIBHeader.BMPInfoHeader2.cx;
430 // szlSourceBmp.cy = mmih.mmXDIBHeader.BMPInfoHeader2.cy;
431
432 // sBitCount = mmih.mmXDIBHeader.BMPInfoHeader2.cBitCount;
433
434 /*
435 * Account for odd bits used in 1bpp or 4bpp images that are
436 * NOT on byte boundaries.
437 */
438
439 cRowBits = pmmih->mmXDIBHeader.BMPInfoHeader2.cx
440 * pmmih->mmXDIBHeader.BMPInfoHeader2.cBitCount;
441 *pcbBytesPerRow = cRowBits >> 3;
442
443 if (cRowBits % 8)
444 ++(*pcbBytesPerRow);
445
446 /*
447 * Ensure the row length in bytes accounts for byte padding.
448 * All bitmap data rows must are aligned on LONG/4-BYTE boundaries.
449 * The data FROM an IOProc should always appear in this form.
450 */
451
452 if (cbPadding = ((*pcbBytesPerRow) % 4))
453 *pcbBytesPerRow += 4 - cbPadding;
454 }
455 }
456 CATCH(excpt1)
457 {
458 arc = ERROR_PROTECTION_VIOLATION;
459 } END_CATCH();
460
461 return arc;
462}
463
464/*
465 *@@ mmhLoadImageBits:
466 *
467 */
468
469APIRET mmhLoadImageBits(HMMIO hmmio, // in: mmio handle from mmhOpenImage
470 PMMIMAGEHEADER pmmih, // in: image header from mmhLoadImageHeader
471 ULONG cbBytesPerRow, // in: padded bytes per scanline from mmhLoadImageHeader
472 PBYTE *ppbBitmapBits) // out: bitmap data allocated via DosAllocMem
473{
474 APIRET arc = NO_ERROR;
475
476 if ( (!ppbBitmapBits)
477 || (!cbBytesPerRow)
478 || (!pmmih)
479 || (!hmmio)
480 )
481 return ERROR_INVALID_PARAMETER;
482
483 if (!G_fFuncsResolved)
484 return MMHERR_MMPM_NOT_INITIALIZED;
485
486 *ppbBitmapBits = NULL;
487
488#ifdef __DEBUG__
489 TRY_LOUD(excpt1)
490#else
491 TRY_QUIET(excpt1)
492#endif
493 {
494 ULONG cScanLines = pmmih->mmXDIBHeader.BMPInfoHeader2.cy;
495
496 if (!(arc = DosAllocMem((PPVOID)ppbBitmapBits,
497 cbBytesPerRow * cScanLines,
498 PAG_COMMIT | PAG_READ | PAG_WRITE)))
499 {
500 ULONG ulRowThis;
501 PBYTE pbCurrent = *ppbBitmapBits;
502
503 // load the bitmap from the file,
504 // one line at a time, starting from the BOTTOM
505 for (ulRowThis = 0;
506 ulRowThis < cScanLines;
507 ulRowThis++)
508 {
509 ULONG cbRead;
510
511 if (!(cbRead = G_mmioRead(hmmio,
512 pbCurrent,
513 cbBytesPerRow)))
514 // 0 means "done" here:
515 break;
516 else if (cbRead == MMIO_ERROR)
517 {
518 arc = MMHERR_MMIOREAD_FAILED;
519 break;
520 }
521
522 pbCurrent += cbBytesPerRow;
523 }
524 } // end if (DosAllocMem((PPVOID)&pRowBuffer,
525 }
526 CATCH(excpt1)
527 {
528 arc = ERROR_PROTECTION_VIOLATION;
529 } END_CATCH();
530
531 if ( (arc)
532 && (*ppbBitmapBits)
533 )
534 {
535 DosFreeMem(*ppbBitmapBits);
536 *ppbBitmapBits = NULL;
537 }
538
539 return arc;
540}
541
542/*
543 *@@ mmhCreateBitmapFromBits:
544 *
545 *@@added V1.0.1 (2003-01-29) [umoeller]
546 */
547
548APIRET mmhCreateBitmapFromBits(PSIZEL pszlTarget, // in: desired size of new bitmap or NULL for no resize
549 PBITMAPINFOHEADER2 pbmihSource, // in: source bitmap format
550 PBYTE pbBitmapBits, // in: source bitmap data
551 HBITMAP *phbmOut) // out: newly created bitmap
552{
553 APIRET arc = NO_ERROR;
554
555 volatile HDC hdcMem = NULLHANDLE; // XWP V1.0.4 (2005-10-09) [pr]
556 volatile HPS hpsMem = NULLHANDLE;
557
558 if (!G_fFuncsResolved)
559 return MMHERR_MMPM_NOT_INITIALIZED;
560
561 if ( (!pbmihSource)
562 || (!pbBitmapBits)
563 || (!phbmOut)
564 )
565 return ERROR_INVALID_PARAMETER;
566
567 *phbmOut = NULLHANDLE;
568
569#ifdef __DEBUG__
570 TRY_LOUD(excpt1)
571#else
572 TRY_QUIET(excpt1)
573#endif
574 {
575 SIZEL szlPS;
576
577 if (pszlTarget)
578 {
579 // caller wants to scale:
580 szlPS.cx = pszlTarget->cx;
581 szlPS.cy = pszlTarget->cy;
582 }
583 else
584 {
585 szlPS.cx = pbmihSource->cx;
586 szlPS.cy = pbmihSource->cy;
587 }
588
589 if (!gpihCreateMemPS(WinQueryAnchorBlock(HWND_DESKTOP),
590 &szlPS,
591 (HDC *) &hdcMem,
592 (HPS *) &hpsMem))
593 arc = MMHERR_GPIGREATEPS_FAILED;
594 else
595 {
596 BITMAPINFOHEADER2 bmihTarget;
597 memcpy(&bmihTarget,
598 pbmihSource,
599 sizeof(bmihTarget));
600
601 bmihTarget.cx = szlPS.cx;
602 bmihTarget.cy = szlPS.cy;
603
604 // I'd love to pass the bits directly to
605 // GpiCreateBitmap, but scaling doesn't
606 // work with CBI_INIT... so we have to do
607 // GpiDrawBits separately.
608 if (!(*phbmOut = GpiCreateBitmap(hpsMem,
609 &bmihTarget,
610 0,
611 0,
612 0)))
613 arc = MMHERR_GPICREATEBITMAP_FAILED;
614 else
615 {
616 // bitmap created:
617
618 if (HBM_ERROR == GpiSetBitmap(hpsMem,
619 *phbmOut))
620 arc = MMHERR_GPISETBITMAP_FAILED;
621 else
622 {
623 POINTL aptl[4];
624 // target bottom left (world coordinates)
625 aptl[0].x = 0;
626 aptl[0].y = 0;
627 // target top right (world coordinates)
628 aptl[1].x = bmihTarget.cx - 1;
629 aptl[1].y = bmihTarget.cy - 1;
630 // source bottom left (device coordinates)
631 aptl[2].x = 0;
632 aptl[2].y = 0;
633 // source top right (device coordinates)
634 aptl[3].x = pbmihSource->cx;
635 aptl[3].y = pbmihSource->cy;
636
637 if (GPI_ERROR == GpiDrawBits(hpsMem,
638 pbBitmapBits,
639 (PBITMAPINFO2)pbmihSource,
640 4,
641 aptl,
642 ROP_SRCCOPY,
643 BBO_IGNORE))
644 arc = MMHERR_GPISETBITMAPBITS_FAILED;
645
646 /*
647 if (GPI_ALTERROR == GpiSetBitmapBits(hpsMem,
648 (LONG)0,
649 (LONG)szlSourceBmp.cy,
650 (PBYTE)pRowBuffer,
651 (PBITMAPINFO2)&bmihSource))
652 arc = MMHERR_GPISETBITMAPBITS_FAILED;
653 */
654 } // end if (GpiSetBitmap(hpsMem
655 } // if (!(*phbmOut = GpiCreateBitmap(hpsMem,
656 }
657 }
658 CATCH(excpt1)
659 {
660 arc = ERROR_PROTECTION_VIOLATION;
661 } END_CATCH();
662
663 if (hpsMem)
664 {
665 // unset bitmap from mem PS
666 GpiSetBitmap(hpsMem,
667 NULLHANDLE);
668
669 if (arc && *phbmOut)
670 {
671 // error:
672 GpiDeleteBitmap(*phbmOut);
673 *phbmOut = NULLHANDLE;
674 }
675
676 GpiDestroyPS(hpsMem);
677 }
678
679 if (hdcMem)
680 DevCloseDC(hdcMem);
681
682 return arc;
683}
684
685/*
686 *@@ mmhLoadImage:
687 * one-shot function for loading an image from a file.
688 * Understands any image file format supported by MMPM/2.
689 *
690 * If fccIOProc is specified, it _must_ represent an
691 * IOProc for an image format. We do not verify this
692 * here.
693 *
694 * Otherwise, if fccIOProc is NULLHANDLE, we automatically
695 * run mmhIdentifyFile and may return MMHERR_NOT_IMAGE_FILE.
696 *
697 * Returns either NO_ERROR or one of the following
698 * error codes:
699 *
700 * -- MMHERR_MMPM_NOT_INITIALIZED: mmhInit not called or
701 * it failed.
702 *
703 * -- MMHERR_NO_IOPROC: file format not understood
704 * by MMPM/2.
705 *
706 * -- MMHERR_NOT_IMAGE_FILE: file format understood, but
707 * is not image file or cannot be translated.
708 *
709 * -- MMHERR_OPEN_FAILED: mmioOpen failed.
710 *
711 * -- MMHERR_INCOMPATIBLE_HEADER: ioproc returned invalid
712 * header.
713 *
714 * -- ERROR_PROTECTION_VIOLATION: probably crash in IOProc.
715 *
716 * plus the error codes from CreateBitmapFromFile().
717 */
718
719APIRET mmhLoadImage(PCSZ pcszFilename, // in: filename to load
720 FOURCC fccIOProc, // in: FOURCC of ioproc to use; if 0, we call mmhIdentifyFile here
721 PSIZEL pszlBmp, // in: desired size of new bitmap or NULL for no resize
722 HBITMAP *phbmOut) // out: newly created bitmap
723{
724 APIRET arc = NO_ERROR;
725
726 volatile PBYTE pbBitmapBits = NULL; // XWP V1.0.4 (2005-10-09) [pr]
727 volatile HMMIO hmmio = NULLHANDLE;
728
729 if ( (!pcszFilename)
730 || (!phbmOut)
731 )
732 return ERROR_INVALID_PARAMETER;
733
734 if (!G_fFuncsResolved)
735 return MMHERR_MMPM_NOT_INITIALIZED;
736
737#ifdef __DEBUG__
738 TRY_LOUD(excpt1)
739#else
740 TRY_QUIET(excpt1)
741#endif
742 {
743 if (!(arc = mmhOpenImage(pcszFilename,
744 fccIOProc,
745 (HMMIO *) &hmmio)))
746 {
747 MMIMAGEHEADER mmihSource;
748 ULONG cbBytesPerRow;
749
750 if (!(arc = mmhLoadImageHeader(hmmio,
751 &mmihSource,
752 &cbBytesPerRow)))
753 {
754 if (!(arc = mmhLoadImageBits(hmmio,
755 &mmihSource,
756 cbBytesPerRow,
757 (PBYTE *) &pbBitmapBits)))
758 {
759 arc = mmhCreateBitmapFromBits(pszlBmp,
760 &mmihSource.mmXDIBHeader.BMPInfoHeader2,
761 pbBitmapBits,
762 phbmOut);
763 } // if (!(arc = mmhLoadImageBits(pcszFilename,
764 } // if (!(arc = mmhLoadImageHeader(pcszFilename,
765 }
766 }
767 CATCH(excpt1)
768 {
769 arc = ERROR_PROTECTION_VIOLATION;
770 } END_CATCH();
771
772 if (pbBitmapBits)
773 DosFreeMem(pbBitmapBits);
774
775 if (hmmio)
776 G_mmioClose(hmmio, 0);
777
778 return arc;
779}
780
Note: See TracBrowser for help on using the repository browser.