Changeset 154 for trunk/src/helpers/gpih.c
- Timestamp:
- Apr 16, 2002, 8:27:19 AM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/gpih.c
r142 r154 58 58 #undef WINH_STANDARDWRAPPERS 59 59 #endif 60 #include "helpers\dosh.h" 60 61 #include "helpers\winh.h" 61 62 #include "helpers\gpih.h" … … 171 172 *@@ gpihQueryDisplayCaps: 172 173 * this returns certain device capabilities of 173 * the Display device. ulIndex must be one of174 * the display device. ulIndex must be one of 174 175 * the indices as described in DevQueryCaps. 175 176 * … … 1668 1669 * yet selected into the HPS. 1669 1670 * 1670 * This function can currently only handle OS/2 1.3 1671 * bitmaps. 1672 * 1673 * Returns the new bitmap handle or NULL upon errors 1674 * (e.g. if an OS/2 2.0 bitmap was accessed). 1675 * 1676 * In the latter case, *pulError is set to one of 1677 * the following: 1678 * -- -1: file not found 1679 * -- -2: malloc failed 1680 * -- -3: the bitmap data could not be read (fopen failed) 1681 * -- -4: file format not recognized (maybe OS/2 2.0 bitmap) 1682 * -- -5: GpiCreateBitmap error (maybe file corrupt) 1671 * If the file contains only a single bitmap, 1672 * this bitmap is used. 1673 * 1674 * If it contains a bitmap array, we use the 1675 * "best bitmap" in the array, which is determined 1676 * from the following criteria (in this order): 1677 * 1678 * -- a device-dependent bitmap, if its device 1679 * resolution is not too large and the given 1680 * HPS can display all its colors; 1681 * 1682 * -- a device-dependent bitmap, if its device 1683 * resolution is not too large, even if the 1684 * given HPS cannot display all its colors; 1685 * 1686 * -- a device-independent bitmap, if the given 1687 * HPS can display all its colors; 1688 * 1689 * -- the first device-independent bitmap in 1690 * the file; 1691 * 1692 * -- the first bitmap in the file. 1693 * 1694 * Support for bitmap arrays was added with V0.9.19. 1695 * I'm not quite sure if the above is the same way 1696 * of selecting the "best bitmap" that GpiLoadBitmap 1697 * would do, but without any documentation, who is 1698 * supposed to know. 1699 * 1700 * Returns: 1701 * 1702 * -- NO_ERROR: *phbm has received new HBITMAP, 1703 * to be freed with GpiDeleteBitmap. 1704 * 1705 * -- ERROR_INVALID_PARAMETER 1706 * 1707 * -- ERROR_INVALID_DATA: file exists, but we 1708 * can't understand its format. 1709 * 1710 * plus the error codes from doshOpen and DosRead. 1683 1711 * 1684 1712 *@@changed V0.9.4 (2000-08-03) [umoeller]: this didn't return NULLHANDLE on errors 1685 */ 1686 1687 HBITMAP gpihLoadBitmapFile(HPS hps, // in: HPS for bmp 1688 PSZ pszBmpFile, // in: bitmap filename 1689 PULONG pulError) // out: error code if FALSE is returned 1690 { 1691 HBITMAP hbm = NULLHANDLE; 1692 PBITMAPFILEHEADER2 pbfh; 1693 1694 struct stat st; 1695 PBYTE pBmpData; 1696 FILE *BmpFile; 1697 1698 if (stat(pszBmpFile, &st) == 0) 1713 *@@changed V0.9.19 (2002-04-14) [umoeller]: rewritten to support bitmap arrays, prototype changed 1714 */ 1715 1716 APIRET gpihLoadBitmapFile(HBITMAP *phbm, // out: bitmap if NO_ERROR 1717 HPS hps, // in: HPS for bmp 1718 PCSZ pcszBmpFile) // in: bitmap filename 1719 { 1720 APIRET arc; 1721 PXFILE pFile; 1722 ULONG cbFile = 0; 1723 1724 if (!hps || !pcszBmpFile || !phbm) 1725 return ERROR_INVALID_PARAMETER; 1726 1727 if (!(arc = doshOpen(pcszBmpFile, 1728 XOPEN_READ_EXISTING | XOPEN_BINARY, 1729 &cbFile, 1730 &pFile))) 1699 1731 { 1700 1701 if ((pBmpData = (PBYTE)malloc(st.st_size))) 1732 PBYTE pData; 1733 if (!(pData = (PBYTE)malloc(cbFile))) 1734 arc = ERROR_NOT_ENOUGH_MEMORY; 1735 else 1736 { 1737 if (!(arc = DosRead(pFile->hf, 1738 pData, 1739 cbFile, 1740 &cbFile))) 1741 { 1742 // check bitmap magic codes 1743 PBITMAPFILEHEADER2 pbfh = (PBITMAPFILEHEADER2)pData; 1744 1745 switch (pbfh->usType) 1746 { 1747 case BFT_BMAP: // "BM" 1748 // single bitmap in file (no array): 1749 if (!(*phbm = GpiCreateBitmap(hps, 1750 &pbfh->bmp2, 1751 CBM_INIT, 1752 (PBYTE)pbfh + pbfh->offBits, 1753 (PBITMAPINFO2)&pbfh->bmp2))) 1754 arc = ERROR_INVALID_DATA; 1755 break; 1756 1757 case BFT_BITMAPARRAY: // "BA" 1758 { 1759 1760 /* 1761 typedef struct _BITMAPARRAYFILEHEADER { 1762 USHORT usType; // Type of structure. 1763 ULONG cbSize; // Size of the BITMAPARRAYFILEHEADER structure in bytes. 1764 ULONG offNext; // Offset of the next BITMAPARRAYFILEHEADER structure from the start of the file. 1765 USHORT cxDisplay; // Device width, in pels. 1766 USHORT cyDisplay; // Device height, in pels. 1767 BITMAPFILEHEADER bfh; // Bitmap file header structure. 1768 } BITMAPARRAYFILEHEADER; 1769 1770 typedef struct _BITMAPARRAYFILEHEADER2 { 1771 USHORT usType; // Type of structure. 1772 ULONG cbSize; // Size of the BITMAPARRAYFILEHEADER2 structure in bytes. 1773 ULONG offNext; // Offset of the next BITMAPARRAYFILEHEADER2 structure from the start of the file. 1774 USHORT cxDisplay; // Device width, in pels. 1775 USHORT cyDisplay; // Device height, in pels. 1776 BITMAPFILEHEADER2 bfh2; // Bitmap file header structure. 1777 } BITMAPARRAYFILEHEADER2; 1778 1779 These two are binarily the same, except for the file header that is contained. 1780 */ 1781 1782 /* OLD FORMAT 1783 1784 typedef struct _BITMAPFILEHEADER { 1785 USHORT usType; // Type of resource the file contains. 1786 ULONG cbSize; // Size of the BITMAPFILEHEADER structure in bytes. 1787 SHORT xHotspot; // Width of hotspot for icons and pointers. 1788 SHORT yHotspot; // Height of hotspot for icons and pointers. 1789 USHORT offBits; // Offset in bytes. 1790 BITMAPINFOHEADER bmp; // Bitmap information header structure. 1791 1792 typedef struct _BITMAPINFOHEADER { 1793 ULONG cbFix; // Length of structure. 1794 USHORT cx; // Bitmap width in pels. 1795 USHORT cy; // Bitmap height in pels. 1796 USHORT cPlanes; // Number of bit planes. 1797 USHORT cBitCount; // Number of bits per pel within a plane. 1798 } BITMAPINFOHEADER; 1799 1800 } BITMAPFILEHEADER; 1801 */ 1802 1803 /* NEW FORMAT 1804 1805 typedef struct _BITMAPFILEHEADER2 { 1806 USHORT usType; // Type of resource the file contains. 1807 ULONG cbSize; // Size of the BITMAPFILEHEADER2 structure in bytes. 1808 SHORT xHotspot; // Width of hotspot for icons and pointers. 1809 SHORT yHotspot; // Height of hotspot for icons and pointers. 1810 USHORT offBits; // Offset in bytes. 1811 BITMAPINFOHEADER2 bmp2; // Bitmap information header structure. 1812 1813 typedef struct _BITMAPINFOHEADER2 { 1814 ULONG cbFix; // Length of structure. 1815 ULONG cx; // Bitmap width in pels. 1816 ULONG cy; // Bitmap height in pels. 1817 USHORT cPlanes; // Number of bit planes. 1818 USHORT cBitCount; // Number of bits per pel within a plane. 1819 ULONG ulCompression; // Compression scheme used to store the bit map. 1820 ULONG cbImage; // Length of bitmap storage data, in bytes. 1821 ULONG cxResolution; // Horizontal component of the resolution of target device. 1822 ULONG cyResolution; // Vertical component of the resolution of target device. 1823 ULONG cclrUsed; // Number of color indexes used. 1824 ULONG cclrImportant; // Minimum number of color indexes for satisfactory appearance of the bit map. 1825 USHORT usUnits; // Units of measure. 1826 USHORT usReserved; // Reserved. 1827 USHORT usRecording; // Recording algorithm. 1828 USHORT usRendering; // Halftoning algorithm. 1829 ULONG cSize1; // Size value 1. 1830 ULONG cSize2; // Size value 2. 1831 ULONG ulColorEncoding; // Color encoding. 1832 ULONG ulIdentifier; // Reserved for application use. 1833 } BITMAPINFOHEADER2; 1834 1835 Because of the unfortunate replacement of USHORTs with ULONGs for 1836 cx and cy in the info header, the cx, cy, and cBitCount data is 1837 NOT the same between old and new formats. Well, IBM, good job. 1838 And ICONEDIT _still_ writes the old format, unfortunately. 1839 1840 } BITMAPFILEHEADER2; 1841 1842 */ 1843 // define a handy union for all the above bullshit 1844 typedef union 1845 { 1846 BITMAPFILEHEADER Old; 1847 BITMAPFILEHEADER2 New; 1848 } BMPUNION, *PBMPUNION; 1849 1850 PBMPUNION puFirstDI = NULL, // first device-independent bitmap 1851 puBestDI = NULL, // best device-independent bitmap 1852 puFirstDD = NULL, // first device-dependent bitmap 1853 puBestDD = NULL, // best device-dependent bitmap 1854 puFirstAny = NULL, // first bitmap of any type 1855 puUse; 1856 1857 // get device resolution for this HPS 1858 // so we can select the "best bitmap" 1859 #define GET_CAPS_FIRST CAPS_WIDTH 1860 #define GET_CAPS_LAST CAPS_COLOR_BITCOUNT 1861 #define GET_NO_CAPS GET_CAPS_LAST - GET_CAPS_FIRST + 1 1862 1863 LONG alCaps[GET_NO_CAPS]; 1864 PBITMAPARRAYFILEHEADER2 pba = (PBITMAPARRAYFILEHEADER2)pData; 1865 1866 DevQueryCaps(GpiQueryDevice(hps), 1867 GET_CAPS_FIRST, 1868 GET_NO_CAPS, 1869 alCaps); 1870 1871 #define BITCOUNT alCaps[CAPS_COLOR_BITCOUNT - GET_CAPS_FIRST] 1872 #define WIDTH alCaps[CAPS_WIDTH - GET_CAPS_FIRST] 1873 #define HEIGHT alCaps[CAPS_HEIGHT - GET_CAPS_FIRST] 1874 1875 // for-all-bitmaps-in-array loop 1876 while (pba) 1877 { 1878 PBMPUNION puThis = (PBMPUNION)&pba->bfh2; 1879 1880 LONG cx = 0, 1881 cy, 1882 cBitCount; 1883 1884 // ignore this if the type isn't "BM" 1885 if (puThis->Old.usType == BFT_BMAP) 1886 { 1887 // fill the three, but watch out, the offsets are 1888 // different between old and new formats 1889 if (puThis->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER)) 1890 { 1891 // old format: 1892 cx = puThis->Old.bmp.cx; 1893 cy = puThis->Old.bmp.cy; 1894 cBitCount = puThis->Old.bmp.cBitCount; 1895 } 1896 else if (puThis->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER2)) 1897 { 1898 // new format: 1899 cx = puThis->New.bmp2.cx; 1900 cy = puThis->New.bmp2.cy; 1901 cBitCount = puThis->New.bmp2.cBitCount; 1902 } 1903 } 1904 1905 if (cx) 1906 { 1907 _Pmpf(("found bmp cxDisplay %d, cyDisplay %d", 1908 pba->cxDisplay, 1909 pba->cyDisplay)); 1910 _Pmpf((" cx %d, cy %d, cBitCount %d", 1911 cx, cy, cBitCount)); 1912 1913 // store first bitmap of any type 1914 if (!puFirstAny) 1915 puFirstAny = puThis; 1916 1917 // check device resolution... device-independent 1918 // one has cxDisplay and cyDisplay set to 0 1919 if ( (!pba->cxDisplay) 1920 && (!pba->cyDisplay) 1921 ) 1922 { 1923 // device-independent: 1924 1925 // store first device-independent bmp 1926 if (!puFirstDI) 1927 puFirstDI = puThis; 1928 1929 if (cBitCount <= BITCOUNT) 1930 // we can display all the colors: 1931 puBestDI = puThis; 1932 } 1933 else 1934 { 1935 // device-dependent: 1936 // ignore if device resolution is too large 1937 if ( (pba->cxDisplay <= WIDTH) 1938 && (pba->cyDisplay <= HEIGHT) 1939 ) 1940 { 1941 if (!puFirstDD) 1942 puFirstDD = puThis; 1943 1944 if (cBitCount <= BITCOUNT) 1945 puBestDD = puThis; 1946 } 1947 } 1948 } // end if cx 1949 1950 // go for next bmp in array 1951 if (pba->offNext) 1952 // another one coming up: 1953 // this ofs is from the beginning of the file 1954 pba = (PBITMAPARRAYFILEHEADER2)(pData + pba->offNext); 1955 else 1956 // no more bitmaps: 1957 break; 1958 } // end while (pba) 1959 1960 if ( (puUse = puBestDD) 1961 || (puUse = puFirstDD) 1962 || (puUse = puBestDI) 1963 || (puUse = puFirstDI) 1964 || (puUse = puFirstAny) 1965 ) 1966 { 1967 PBITMAPINFOHEADER2 pbih2; 1968 PBYTE pbInitData; 1969 1970 if (puUse->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER)) 1971 { 1972 // old format: 1973 pbih2 = (PBITMAPINFOHEADER2)&puUse->Old.bmp; 1974 pbInitData = (PBYTE)pData + puUse->Old.offBits; 1975 } 1976 else 1977 { 1978 // new format: 1979 pbih2 = &puUse->New.bmp2; 1980 pbInitData = (PBYTE)pData + puUse->New.offBits; 1981 } 1982 1983 if (!(*phbm = GpiCreateBitmap(hps, 1984 pbih2, 1985 CBM_INIT, 1986 pbInitData, 1987 (PBITMAPINFO2)pbih2))) 1988 arc = ERROR_INVALID_DATA; 1989 } 1990 else 1991 arc = ERROR_INVALID_DATA; 1992 } 1993 break; 1994 } 1995 } 1996 1997 free(pData); 1998 } 1999 2000 doshClose(&pFile); 2001 } 2002 2003 return arc; 2004 2005 /* if (stat(pszBmpFile, &st) == 0) 2006 { 2007 2008 if ((pData = (PBYTE)malloc(st.st_size))) 1702 2009 { 1703 2010 // open bmp file … … 1705 2012 { 1706 2013 // read bmp data 1707 fread(p BmpData, 1, st.st_size, BmpFile);2014 fread(pData, 1, st.st_size, BmpFile); 1708 2015 fclose(BmpFile); 1709 2016 1710 2017 // check bitmap magic codes 1711 if (p BmpData[0] == 'B' && pBmpData[1] == 'M')2018 if (pData[0] == 'B' && pData[1] == 'M') 1712 2019 { 1713 pbfh = (PBITMAPFILEHEADER2)p BmpData;2020 pbfh = (PBITMAPFILEHEADER2)pData; 1714 2021 hbm = GpiCreateBitmap(hps, 1715 2022 &pbfh->bmp2, 1716 2023 CBM_INIT, 1717 (p BmpData + pbfh->offBits),2024 (pData + pbfh->offBits), 1718 2025 (PBITMAPINFO2)&pbfh->bmp2); 1719 2026 … … 1731 2038 *pulError = -3; 1732 2039 1733 free(p BmpData);2040 free(pData); 1734 2041 } 1735 2042 else if (pulError) … … 1739 2046 *pulError = -1; 1740 2047 1741 return (hbm); 2048 return (hbm);*/ 1742 2049 } 1743 2050
Note:
See TracChangeset
for help on using the changeset viewer.