Image.st
changeset 193 3abcc2ee1641
parent 191 a81db32ff94b
child 194 7ba58753a6b7
equal deleted inserted replaced
192:13a9d4bafa7e 193:3abcc2ee1641
    27 
    27 
    28 Image comment:'
    28 Image comment:'
    29 COPYRIGHT (c) 1991 by Claus Gittinger
    29 COPYRIGHT (c) 1991 by Claus Gittinger
    30 	      All Rights Reserved
    30 	      All Rights Reserved
    31 
    31 
    32 $Header: /cvs/stx/stx/libview/Image.st,v 1.41 1995-09-21 11:39:49 claus Exp $
    32 $Header: /cvs/stx/stx/libview/Image.st,v 1.42 1995-10-23 16:59:09 cg Exp $
    33 '!
    33 '!
    34 
    34 
    35 !Image class methodsFor:'documentation'!
    35 !Image class methodsFor:'documentation'!
    36 
    36 
    37 copyright
    37 copyright
    48 "
    48 "
    49 !
    49 !
    50 
    50 
    51 version
    51 version
    52 "
    52 "
    53 $Header: /cvs/stx/stx/libview/Image.st,v 1.41 1995-09-21 11:39:49 claus Exp $
    53 $Header: /cvs/stx/stx/libview/Image.st,v 1.42 1995-10-23 16:59:09 cg Exp $
    54 "
    54 "
    55 !
    55 !
    56 
    56 
    57 documentation
    57 documentation
    58 "
    58 "
   159 
   159 
   160     depth == 1 ifTrue:[^ Depth1Image].
   160     depth == 1 ifTrue:[^ Depth1Image].
   161     depth == 2 ifTrue:[^ Depth2Image].
   161     depth == 2 ifTrue:[^ Depth2Image].
   162     depth == 4 ifTrue:[^ Depth4Image].
   162     depth == 4 ifTrue:[^ Depth4Image].
   163     depth == 8 ifTrue:[^ Depth8Image].
   163     depth == 8 ifTrue:[^ Depth8Image].
       
   164     depth == 16 ifTrue:[^ Depth16Image].
   164     depth == 24 ifTrue:[^ Depth24Image].
   165     depth == 24 ifTrue:[^ Depth24Image].
   165     ^ self
   166     ^ self
   166 ! !
   167 ! !
   167 
   168 
   168 !Image class methodsFor:'misc'!
   169 !Image class methodsFor:'misc'!
  1769     visual := aDevice visualType.
  1770     visual := aDevice visualType.
  1770     (visual == #StaticGray) ifTrue:[
  1771     (visual == #StaticGray) ifTrue:[
  1771 	^ self rgbImageAsGreyFormOn:aDevice
  1772 	^ self rgbImageAsGreyFormOn:aDevice
  1772     ].
  1773     ].
  1773     (visual == #TrueColor) ifTrue:[
  1774     (visual == #TrueColor) ifTrue:[
  1774 	^ self rgbImageAsTrueFormOn:aDevice
  1775 	^ self rgbImageAsTrueColorFormOn:aDevice
  1775     ].
  1776     ].
  1776     ^ self rgbImageAsPseudoFormOn:aDevice
  1777     ^ self rgbImageAsPseudoFormOn:aDevice
  1777 !
  1778 !
  1778 
  1779 
  1779 rgbImageAsGreyFormOn:aDevice
  1780 rgbImageAsGreyFormOn:aDevice
  1855 
  1856 
  1856 rgbImageAsPseudoFormOn:aDevice
  1857 rgbImageAsPseudoFormOn:aDevice
  1857     "return a pseudocolor form from the rgb-picture"
  1858     "return a pseudocolor form from the rgb-picture"
  1858 
  1859 
  1859     ^ self subclassResponsibility
  1860     ^ self subclassResponsibility
       
  1861 !
       
  1862 
       
  1863 rgbImageAsTrueColorFormOn:aDevice
       
  1864     "return a truecolor form from the rgb-picture."
       
  1865 
       
  1866     |bestFormat usedDeviceDepth usedDeviceBitsPerPixel depth
       
  1867      myDepth form imageBits destIndex srcIndex 
       
  1868      rightShiftR rightShiftG rightShiftB shiftRed shiftGreen shiftBlue ok|
       
  1869 
       
  1870     bestFormat := self bestSupportedImageFormatFor:aDevice.
       
  1871     usedDeviceDepth := bestFormat at:1.
       
  1872     usedDeviceBitsPerPixel := bestFormat at:2.
       
  1873 
       
  1874     rightShiftR := (8 - aDevice bitsRed).
       
  1875     rightShiftG := (8 - aDevice bitsGreen).
       
  1876     rightShiftB := (8 - aDevice bitsBlue).
       
  1877 
       
  1878     shiftRed := aDevice shiftRed.
       
  1879     shiftGreen := aDevice shiftGreen.
       
  1880     shiftBlue := aDevice shiftBlue.
       
  1881 
       
  1882     myDepth := self bitsPerPixel.
       
  1883     myDepth == usedDeviceBitsPerPixel ifTrue:[
       
  1884 	"/
       
  1885 	"/ first, the trivial case, where the depths match
       
  1886 	"/
       
  1887 	imageBits := bytes.
       
  1888     ] ifFalse:[
       
  1889 	"/
       
  1890 	"/ for now, only a few formats are supported
       
  1891 	"/
       
  1892 	((myDepth == 24) and:[usedDeviceBitsPerPixel == 16]) ifTrue:[
       
  1893 	    imageBits := ByteArray uninitializedNew:(width * height * 2).
       
  1894 
       
  1895 	    "/ now, walk over the image and compose 16bit values from the r/g/b triples
       
  1896 
       
  1897 	    ok := false.
       
  1898 %{
       
  1899 #ifdef NOTDEF
       
  1900 	    if (__isSmallInteger(_INST(height))
       
  1901 	     && __isSmallInteger(_INST(width))
       
  1902 	     && __isSmallInteger(rightShiftR)
       
  1903 	     && __isSmallInteger(rightShiftG)
       
  1904 	     && __isSmallInteger(rightShiftB)
       
  1905 	     && __isSmallInteger(shiftRed)
       
  1906 	     && __isSmallInteger(shiftGreen)
       
  1907 	     && __isSmallInteger(shiftBlue)
       
  1908 	     && __isByteArray(_INST(bytes))
       
  1909 	     && __isByteArray(imageBits)) {
       
  1910 		int rShRed = __intVal(rightShiftR),
       
  1911 		    rShGreen = __intVal(rightShiftG),
       
  1912 		    rShBlue = __intVal(rightShiftB),
       
  1913 		    lShRed = __intVal(shiftRed),
       
  1914 		    lShGreen = __intVal(shiftGreen),
       
  1915 		    lShBlue = __intVal(shiftBlue);
       
  1916 		int x, y;
       
  1917 
       
  1918 		unsigned char *srcPtr = _ByteArrayInstPtr(_INST(bytes))->ba_element;
       
  1919 		char *dstPtr = _ByteArrayInstPtr(imageBits)->ba_element;
       
  1920 
       
  1921 		for (y=__intVal(_INST(height)); y > 0; y--) {
       
  1922 		    for (x=__intVal(_INST(width)); x > 0; x--) {
       
  1923 			unsigned r, g, b, v;
       
  1924 
       
  1925 			r = srcPtr[0] >> rShRed;
       
  1926 			g = srcPtr[1] >> rShGreen;
       
  1927 			b = srcPtr[2] >> rShBlue;
       
  1928 			v = r << lShRed;
       
  1929 			v |= (g << lShGreen);
       
  1930 			v |= (b << lShBlue);
       
  1931 #ifdef MSBFIRST
       
  1932 			((short *)dstPtr)[0] = v;
       
  1933 #else
       
  1934 			dstPtr[0] = (v>>8) & 0xFF;
       
  1935 			dstPtr[1] = (v) & 0xFF;
       
  1936 #endif
       
  1937 			dstPtr += 2;
       
  1938 			srcPtr += 3;
       
  1939 		    }
       
  1940 		}
       
  1941 		ok = true;
       
  1942 	    }
       
  1943 #endif
       
  1944 %}.
       
  1945 	    ok ifFalse:[
       
  1946 		"/ this fallback is only executed if type is not
       
  1947 		"/ what the primitive expects; for example, if the bytes-instvar
       
  1948 		"/ is not a ByteArray
       
  1949 
       
  1950 		rightShiftR := rightShiftR negated.
       
  1951 		rightShiftG := rightShiftG negated.
       
  1952 		rightShiftB := rightShiftB negated.
       
  1953 
       
  1954 		destIndex := 1.
       
  1955 		srcIndex := 1.
       
  1956 
       
  1957 		0 to:height-1 do:[:y |
       
  1958 		    0 to:width-1 do:[:x |
       
  1959 			|r g b v|
       
  1960 
       
  1961 			r := bytes at:srcIndex.
       
  1962 			g := bytes at:(srcIndex + 1).
       
  1963 			b := bytes at:(srcIndex + 2).
       
  1964 
       
  1965 			r := r bitShift:rightShiftR.
       
  1966 			g := g bitShift:rightShiftG.
       
  1967 			b := b bitShift:rightShiftB.
       
  1968 
       
  1969 			v := r bitShift:shiftRed.
       
  1970 			v := v bitOr:(g bitShift:shiftGreen).
       
  1971 			v := v bitOr:(b bitShift:shiftBlue).
       
  1972 
       
  1973 			imageBits wordAt:destIndex put:v MSB:true.
       
  1974 			destIndex := destIndex + 2.
       
  1975 			srcIndex := srcIndex + 3.
       
  1976 		    ]
       
  1977 		]
       
  1978 	    ]
       
  1979 	] ifFalse:[
       
  1980 	    ((myDepth == 24) and:[usedDeviceBitsPerPixel == 32]) ifTrue:[
       
  1981 		imageBits := ByteArray uninitializedNew:(width * height * 4).
       
  1982 
       
  1983 		"/ now, walk over the image and compose 32bit values from the r/g/b triples
       
  1984 
       
  1985 		ok := false.
       
  1986 %{
       
  1987 #ifdef NOTDEF
       
  1988 		if (__isSmallInteger(_INST(height))
       
  1989 		 && __isSmallInteger(_INST(width))
       
  1990 		 && __isSmallInteger(rightShiftR)
       
  1991 		 && __isSmallInteger(rightShiftG)
       
  1992 		 && __isSmallInteger(rightShiftB)
       
  1993 		 && __isSmallInteger(shiftRed)
       
  1994 		 && __isSmallInteger(shiftGreen)
       
  1995 		 && __isSmallInteger(shiftBlue)
       
  1996 		 && __isByteArray(_INST(bytes))
       
  1997 		 && __isByteArray(imageBits)) {
       
  1998 		    int rShRed = __intVal(rightShiftR),
       
  1999 			rShGreen = __intVal(rightShiftG),
       
  2000 			rShBlue = __intVal(rightShiftB),
       
  2001 			lShRed = __intVal(shiftRed),
       
  2002 			lShGreen = __intVal(shiftGreen),
       
  2003 			lShBlue = __intVal(shiftBlue);
       
  2004 		    int x, y;
       
  2005 
       
  2006 		    unsigned char *srcPtr = _ByteArrayInstPtr(_INST(bytes))->ba_element;
       
  2007 		    char *dstPtr = _ByteArrayInstPtr(imageBits)->ba_element;
       
  2008 
       
  2009 		    if ((rShRed == 0)
       
  2010 		     && (rShGreen == 0)
       
  2011 		     && (rShBlue == 0)) {
       
  2012 			for (y=__intVal(_INST(height)); y > 0; y--) {
       
  2013 			    for (x=__intVal(_INST(width)); x > 0; x--) {
       
  2014 				unsigned v;
       
  2015 
       
  2016 				v = srcPtr[0] << lShRed;
       
  2017 				v |= (srcPtr[1] << lShGreen);
       
  2018 				v |= (srcPtr[2] << lShBlue);
       
  2019 #ifdef MSBFIRST
       
  2020 				((int *)dstPtr)[0] = v;
       
  2021 #else
       
  2022 				dstPtr[0] = (v>>24) & 0xFF;
       
  2023 				dstPtr[1] = (v>>16) & 0xFF;
       
  2024 				dstPtr[2] = (v>>8) & 0xFF;
       
  2025 				dstPtr[3] = (v) & 0xFF;
       
  2026 #endif
       
  2027 				dstPtr += 4;
       
  2028 				srcPtr += 3;
       
  2029 			    }
       
  2030 			}
       
  2031 		    } else {
       
  2032 			for (y=__intVal(_INST(height)); y > 0; y--) {
       
  2033 			    for (x=__intVal(_INST(width)); x > 0; x--) {
       
  2034 				unsigned r, g, b, v;
       
  2035 
       
  2036 				r = srcPtr[0] >> rShRed;
       
  2037 				g = srcPtr[1] >> rShGreen;
       
  2038 				b = srcPtr[2] >> rShBlue;
       
  2039 				v = r << lShRed;
       
  2040 				v |= (g << lShGreen);
       
  2041 				v |= (b << lShBlue);
       
  2042 #ifdef MSBFIRST
       
  2043 				((int *)dstPtr)[0] = v;
       
  2044 #else
       
  2045 				dstPtr[0] = (v>>24) & 0xFF;
       
  2046 				dstPtr[1] = (v>>16) & 0xFF;
       
  2047 				dstPtr[2] = (v>>8) & 0xFF;
       
  2048 				dstPtr[3] = (v) & 0xFF;
       
  2049 #endif
       
  2050 				dstPtr += 4;
       
  2051 				srcPtr += 3;
       
  2052 			    }
       
  2053 			}
       
  2054 		    }
       
  2055 		    ok = true;
       
  2056 		}
       
  2057 #endif
       
  2058 %}.
       
  2059 		ok ifFalse:[
       
  2060 		    "/ this fallback is only executed if type is not
       
  2061 		    "/ what the primitive expects; for example, if the bytes-instvar
       
  2062 		    "/ is not a ByteArray
       
  2063 
       
  2064 		    rightShiftR := rightShiftR negated.
       
  2065 		    rightShiftG := rightShiftG negated.
       
  2066 		    rightShiftB := rightShiftB negated.
       
  2067 
       
  2068 		    destIndex := 1.
       
  2069 		    srcIndex := 1.
       
  2070 
       
  2071 		    0 to:height-1 do:[:y |
       
  2072 			0 to:width-1 do:[:x |
       
  2073 			    |r g b v|
       
  2074 
       
  2075 			    r := bytes at:srcIndex.
       
  2076 			    g := bytes at:(srcIndex + 1).
       
  2077 			    b := bytes at:(srcIndex + 2).
       
  2078 
       
  2079 			    r := r bitShift:rightShiftR.
       
  2080 			    g := g bitShift:rightShiftG.
       
  2081 			    b := b bitShift:rightShiftB.
       
  2082 
       
  2083 			    v := r bitShift:shiftRed.
       
  2084 			    v := v bitOr:(g bitShift:shiftGreen).
       
  2085 			    v := v bitOr:(b bitShift:shiftBlue).
       
  2086 
       
  2087 			    imageBits doubleWordAt:destIndex put:v MSB:true.
       
  2088 			    destIndex := destIndex + 4.
       
  2089 			    srcIndex := srcIndex + 3.
       
  2090 			]
       
  2091 		    ]
       
  2092 		]
       
  2093 	    ].
       
  2094 	]
       
  2095     ].
       
  2096 
       
  2097     imageBits isNil ifTrue:[            
       
  2098 	'IMAGE: unimplemented trueColor depth in rgbImageAsTrueColorFormOn:' errorPrintNL.
       
  2099 	^ self rgbImageAsMonoFormOn:aDevice
       
  2100     ].
       
  2101 
       
  2102     form := Form width:width height:height depth:usedDeviceDepth on:aDevice.
       
  2103     form isNil ifTrue:[
       
  2104 	'IMAGE: display bitmap creation failed' errorPrintNL.
       
  2105 	^ nil
       
  2106     ].
       
  2107     form initGC.
       
  2108 
       
  2109     form 
       
  2110 	copyBitsFrom:imageBits bitsPerPixel:usedDeviceBitsPerPixel depth:usedDeviceDepth 
       
  2111 	       width:width height:height 
       
  2112 		   x:0 y:0 toX:0 y:0. 
       
  2113 
       
  2114     ^ form
       
  2115 
       
  2116     "Created: 21.10.1995 / 02:15:18 / cg"
       
  2117     "Modified: 21.10.1995 / 19:30:11 / cg"
  1860 ! !
  2118 ! !
  1861 
  2119 
  1862 !Image methodsFor:'converting palette images'!
  2120 !Image methodsFor:'converting palette images'!
  1863 
  2121 
  1864 paletteImageAsFormOn:aDevice
  2122 paletteImageAsFormOn:aDevice
  1865     "return a device-form for the palette-image receiver"
  2123     "return a device-form for the palette-image receiver"
  1866 
  2124 
  1867     (aDevice visualType == #StaticGray) ifTrue:[
  2125     |type|
       
  2126 
       
  2127     ((type := aDevice visualType) == #StaticGray) ifTrue:[
  1868 	(aDevice depth == 8) ifTrue:[
  2128 	(aDevice depth == 8) ifTrue:[
  1869 	    ^ self paletteImageAsGreyFormOn:aDevice
  2129 	    ^ self paletteImageAsGreyFormOn:aDevice
  1870 	].
  2130 	].
  1871 
  2131 
  1872 	DitherAlgorithm == #pattern ifTrue:[
  2132 	DitherAlgorithm == #pattern ifTrue:[
  1877 	    ^ self paletteImageAs2PlaneFormOn:aDevice
  2137 	    ^ self paletteImageAs2PlaneFormOn:aDevice
  1878 	].
  2138 	].
  1879 
  2139 
  1880 	^ self paletteImageAsMonoFormOn:aDevice
  2140 	^ self paletteImageAsMonoFormOn:aDevice
  1881     ].
  2141     ].
  1882     ^ self paletteImageAsPseudoFormOn:aDevice
  2142     (type == #TrueColor) ifTrue:[
       
  2143 	^ self paletteImageAsTrueColorFormOn:aDevice
       
  2144     ].
       
  2145     (type == #PseudoColor) ifTrue:[
       
  2146 	^ self paletteImageAsPseudoFormOn:aDevice
       
  2147     ].
       
  2148     "/ dump fallback: every device should implement b&w images ...
       
  2149     ^ self paletteImageAsMonoFormOn:aDevice
  1883 !
  2150 !
  1884 
  2151 
  1885 paletteImageAsMonoFormOn:aDevice
  2152 paletteImageAsMonoFormOn:aDevice
  1886     "return a 1-bit mono-deviceForm from the palette image"
  2153     "return a 1-bit mono-deviceForm from the palette image"
  1887 
  2154 
  1928 
  2195 
  1929 paletteImageAsPatternDitheredGreyFormOn:aDevice
  2196 paletteImageAsPatternDitheredGreyFormOn:aDevice
  1930     "return a dithered grey-deviceForm from the palette image."
  2197     "return a dithered grey-deviceForm from the palette image."
  1931 
  2198 
  1932     ^ self subclassResponsibility
  2199     ^ self subclassResponsibility
       
  2200 !
       
  2201 
       
  2202 paletteImageAsTrueColorFormOn:aDevice
       
  2203     "return a true-color device-form for the palette-image receiver."
       
  2204 
       
  2205     |depth myDepth nColors colorValues 
       
  2206      scaleRed scaleGreen scaleBlue redShift greenShift blueShift
       
  2207      form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel destIndex ok|
       
  2208 
       
  2209     "/ this is a slow fallback method; this ought to be
       
  2210     "/ redefined in DepthxImage for more performance.
       
  2211 
       
  2212     depth := aDevice depth.
       
  2213     myDepth := self bitsPerPixel.
       
  2214     myDepth > 12 ifTrue:[
       
  2215 	'IMAGE: depth > 12 not supported' errorPrintNL.
       
  2216 	^ nil
       
  2217     ].
       
  2218 
       
  2219     "/ gather r/g/b values for all colors in the map ...
       
  2220 
       
  2221     nColors := colorMap size.
       
  2222 
       
  2223     "/ precompute scales to map from 0..100 into devices range
       
  2224     "/ (this may be different for the individual components)
       
  2225 
       
  2226     scaleRed := ((1 bitShift:aDevice bitsRed) - 1) / 100.
       
  2227     scaleGreen := ((1 bitShift:aDevice bitsGreen) - 1) / 100.
       
  2228     scaleBlue := ((1 bitShift:aDevice bitsBlue) - 1) / 100.
       
  2229     redShift := aDevice shiftRed.
       
  2230     greenShift := aDevice shiftGreen.
       
  2231     blueShift := aDevice shiftBlue.
       
  2232 
       
  2233     colorValues := Array uninitializedNew:nColors.
       
  2234 
       
  2235     1 to:nColors do:[:index |
       
  2236 	|clr rv gv bv v|
       
  2237 
       
  2238 	clr := colorMap at:index.
       
  2239 	clr notNil ifTrue:[
       
  2240 	    rv := (clr red * scaleRed) rounded.
       
  2241 	    gv := (clr green * scaleGreen) rounded.
       
  2242 	    bv := (clr blue * scaleBlue) rounded.
       
  2243 
       
  2244 	    v := rv bitShift:redShift.
       
  2245 	    v := v bitOr:(gv bitShift:greenShift).
       
  2246 	    v := v bitOr:(bv bitShift:blueShift).
       
  2247 	    colorValues at:index put:v.
       
  2248 "/ clr print. ' ' print.
       
  2249 "/ rv print. ' ' print. gv print. ' ' print. bv print. ' ' print.
       
  2250 "/ ' -> ' print. v printNL.
       
  2251 
       
  2252 	]
       
  2253     ].
       
  2254 
       
  2255     bestFormat := self bestSupportedImageFormatFor:aDevice.
       
  2256     usedDeviceDepth := bestFormat at:1.
       
  2257     usedDeviceBitsPerPixel := bestFormat at:2.
       
  2258 
       
  2259     "/ for now, only support some depths
       
  2260 
       
  2261     usedDeviceBitsPerPixel == 16 ifTrue:[
       
  2262 	imageBits := ByteArray uninitializedNew:(width * height * 2).
       
  2263 
       
  2264 	"/ now, walk over the image and replace
       
  2265 	"/ colorMap indices by color values in the bits array
       
  2266 
       
  2267 	ok := false.
       
  2268 %{
       
  2269 #ifdef NOTDEF
       
  2270 	if (__isSmallInteger(_INST(height))
       
  2271 	 && __isSmallInteger(_INST(width))
       
  2272 	 && __isArray(colorValues)
       
  2273 	 && __isByteArray(_INST(bytes))
       
  2274 	 && (myDepth == __MKSMALLINT(8))
       
  2275 	 && __isByteArray(imageBits)) {
       
  2276 	    int x, y;
       
  2277 
       
  2278 	    unsigned char *srcPtr = _ByteArrayInstPtr(_INST(bytes))->ba_element;
       
  2279 	    char *dstPtr = _ByteArrayInstPtr(imageBits)->ba_element;
       
  2280 	    OBJ *ap = __ArrayInstPtr(colorValues)->a_element;
       
  2281 
       
  2282 	    for (y=__intVal(_INST(height)); y > 0; y--) {
       
  2283 		for (x=__intVal(_INST(width)); x > 0; x--) {
       
  2284 		    unsigned idx, v;
       
  2285 		    OBJ clr;
       
  2286 
       
  2287 		    idx = *srcPtr++;
       
  2288 		    clr = ap[idx];
       
  2289 		    v = __intVal(clr);
       
  2290 #ifdef MSBFIRST
       
  2291 		    ((short *)dstPtr)[0] = v;
       
  2292 #else
       
  2293 		    dstPtr[0] = (v>>8) & 0xFF;
       
  2294 		    dstPtr[1] = (v) & 0xFF;
       
  2295 #endif
       
  2296 		    dstPtr += 2;
       
  2297 		}
       
  2298 	    }
       
  2299 	    ok = true;
       
  2300 	}
       
  2301 #endif
       
  2302 %}.
       
  2303 	ok ifFalse:[
       
  2304 	    "/ this fallback is only executed if type is not
       
  2305 	    "/ what the primitive expects; for example, if the bytes-instvar
       
  2306 	    "/ is not a ByteArray
       
  2307 	    destIndex := 1.
       
  2308 	    0 to:height-1 do:[:y |
       
  2309 		0 to:width-1 do:[:x |
       
  2310 		    |colorIndex|
       
  2311 
       
  2312 		    colorIndex := self valueAtX:x y:y.
       
  2313 		    imageBits wordAt:destIndex put:(colorValues at:colorIndex + 1) MSB:true.
       
  2314 		    destIndex := destIndex + 2.
       
  2315 		]
       
  2316 	    ]
       
  2317 	]
       
  2318     ] ifFalse:[
       
  2319 	usedDeviceBitsPerPixel == 32 ifTrue:[
       
  2320 	    imageBits := ByteArray uninitializedNew:(width * height * 4).
       
  2321 
       
  2322 	    "/ now, walk over the image and replace
       
  2323 	    "/ colorMap indices by color values in the bits array
       
  2324 
       
  2325 	    ok := false.
       
  2326 %{
       
  2327 #ifdef NOTDEF
       
  2328 	    if (__isSmallInteger(_INST(height))
       
  2329 	     && __isSmallInteger(_INST(width))
       
  2330 	     && __isArray(colorValues)
       
  2331 	     && __isByteArray(_INST(bytes))
       
  2332 	     && (myDepth == __MKSMALLINT(8))
       
  2333 	     && __isByteArray(imageBits)) {
       
  2334 		int x, y;
       
  2335 
       
  2336 		unsigned char *srcPtr = _ByteArrayInstPtr(_INST(bytes))->ba_element;
       
  2337 		char *dstPtr = _ByteArrayInstPtr(imageBits)->ba_element;
       
  2338 		OBJ *ap = __ArrayInstPtr(colorValues)->a_element;
       
  2339 
       
  2340 		for (y=__intVal(_INST(height)); y > 0; y--) {
       
  2341 		    for (x=__intVal(_INST(width)); x > 0; x--) {
       
  2342 			unsigned idx, v;
       
  2343 			OBJ clr;
       
  2344 
       
  2345 			idx = *srcPtr++;
       
  2346 			clr = ap[idx];
       
  2347 			v = __intVal(clr);
       
  2348 #ifdef MSBFIRST
       
  2349 			((short *)dstPtr)[0] = v;
       
  2350 #else
       
  2351 			dstPtr[0] = (v>>24) & 0xFF;
       
  2352 			dstPtr[1] = (v>>16) & 0xFF;
       
  2353 			dstPtr[2] = (v>>8) & 0xFF;
       
  2354 			dstPtr[3] = (v) & 0xFF;
       
  2355 #endif
       
  2356 			dstPtr += 4;
       
  2357 		    }
       
  2358 		}
       
  2359 		ok = true;
       
  2360 	    }
       
  2361 #endif
       
  2362 %}.
       
  2363 	    ok ifFalse:[
       
  2364 		destIndex := 1.
       
  2365 		0 to:height-1 do:[:y |
       
  2366 		    0 to:width-1 do:[:x |
       
  2367 			|colorIndex|
       
  2368 
       
  2369 			colorIndex := self valueAtX:x y:y.
       
  2370 			imageBits doubleWordAt:destIndex put:(colorValues at:colorIndex + 1) MSB:true.
       
  2371 			destIndex := destIndex + 4.
       
  2372 		    ]
       
  2373 		]
       
  2374 	    ]
       
  2375 	]
       
  2376     ].
       
  2377 
       
  2378     imageBits isNil ifTrue:[            
       
  2379 	'IMAGE: unimplemented trueColor depth in paletteImageAsTrueColorFormOn:' errorPrintNL.
       
  2380 	^ self paletteImageAsMonoFormOn:aDevice
       
  2381     ].
       
  2382 
       
  2383     form :=
       
  2384     form := Form width:width height:height depth:usedDeviceDepth on:aDevice.
       
  2385     form isNil ifTrue:[^ nil].
       
  2386     form initGC.
       
  2387 
       
  2388     form 
       
  2389 	copyBitsFrom:imageBits bitsPerPixel:usedDeviceBitsPerPixel depth:usedDeviceDepth 
       
  2390 	       width:width height:height 
       
  2391 		   x:0 y:0 toX:0 y:0. 
       
  2392 
       
  2393     ^ form
       
  2394 
       
  2395     "Created: 20.10.1995 / 22:05:10 / cg"
       
  2396     "Modified: 21.10.1995 / 19:30:26 / cg"
  1933 ! !
  2397 ! !
  1934 
  2398 
  1935 !Image methodsFor:'converting greyscale images'!
  2399 !Image methodsFor:'converting greyscale images'!
  1936 
  2400 
  1937 greyImageAsFormOn:aDevice
  2401 greyImageAsFormOn:aDevice
  1997     ].
  2461     ].
  1998 
  2462 
  1999 
  2463 
  2000     (aDevice visualType == #PseudoColor or:[aDevice visualType == #GrayScale]) ifTrue:[
  2464     (aDevice visualType == #PseudoColor or:[aDevice visualType == #GrayScale]) ifTrue:[
  2001 	^ self greyImageAsPseudoFormOn:aDevice
  2465 	^ self greyImageAsPseudoFormOn:aDevice
       
  2466     ].
       
  2467 
       
  2468     (aDevice visualType == #TrueColor) ifTrue:[
       
  2469 	^ self greyImageAsTrueColorFormOn:aDevice
  2002     ].
  2470     ].
  2003 
  2471 
  2004     self error:'cannot convert this format'.
  2472     self error:'cannot convert this format'.
  2005     ^ nil
  2473     ^ nil
  2006 !
  2474 !
  2211     f initGC.
  2679     f initGC.
  2212     aDevice drawBits:wideBits depth:8 width:width height:height
  2680     aDevice drawBits:wideBits depth:8 width:width height:height
  2213 		       x:0 y:0
  2681 		       x:0 y:0
  2214 		    into:(f id) x:0 y:0 width:width height:height with:(f gcId).
  2682 		    into:(f id) x:0 y:0 width:width height:height with:(f gcId).
  2215     ^ f
  2683     ^ f
       
  2684 !
       
  2685 
       
  2686 greyImageAsTrueColorFormOn:aDevice
       
  2687     "return a true-color device-form for the grey-image receiver.
       
  2688      TODO: the pixel loops ought to be implemented as inline primitive code ..."
       
  2689 
       
  2690     |depth myDepth nColors colorValues
       
  2691      scaleDown scaleRed scaleGreen scaleBlue redShift blueShift greenShift
       
  2692      form imageBitsdestIndex 
       
  2693      bestFormat usedDeviceDepth usedDeviceBitsPerPixel imageBits destIndex|
       
  2694 
       
  2695     "/ this is a slow fallback method; this ought to be
       
  2696     "/ redefined in DepthxImage for more performance.
       
  2697 
       
  2698     depth := aDevice depth.
       
  2699     myDepth := self depth.
       
  2700     myDepth > 12 ifTrue:[
       
  2701 	self error:'unsupported trueColor depth in greyImageAsTrueColorFormOn:'.
       
  2702 	^ nil
       
  2703     ].
       
  2704 
       
  2705     "/ compute scale to map from my pixels into devices range
       
  2706 
       
  2707     scaleDown := 1 bitShift:myDepth.
       
  2708     scaleRed := (1 bitShift:aDevice bitsRed).
       
  2709     scaleGreen := (1 bitShift:aDevice bitsGreen).
       
  2710     scaleBlue := (1 bitShift:aDevice bitsBlue).
       
  2711     redShift := aDevice shiftRed.
       
  2712     greenShift := aDevice shiftGreen.
       
  2713     blueShift := aDevice shiftBlue.
       
  2714 
       
  2715     nColors := (1 bitShift:myDepth).
       
  2716     colorValues := Array new:nColors.
       
  2717     1 to:nColors do:[:i |
       
  2718 	|v gv bv rv nv|
       
  2719 
       
  2720 	"/ scale down to 0..1
       
  2721 	v := (i-1) / scaleDown.
       
  2722 	rv := (v * scaleRed) rounded.
       
  2723 	gv := (v * scaleGreen) rounded.
       
  2724 	bv := (v * scaleBlue) rounded.
       
  2725 	nv := rv bitShift:redShift.
       
  2726 	nv := nv bitOr:(gv bitShift:greenShift).
       
  2727 	nv := nv bitOr:(bv bitShift:blueShift).
       
  2728 	colorValues at:i put:nv
       
  2729     ].
       
  2730     photometric == #whiteIs0 ifTrue:[
       
  2731 	"/ reverse the order; 0 is brightest
       
  2732 	colorValues reverse
       
  2733     ].
       
  2734 
       
  2735     bestFormat := self bestSupportedImageFormatFor:aDevice.
       
  2736     usedDeviceDepth := bestFormat at:1.
       
  2737     usedDeviceBitsPerPixel := bestFormat at:2.
       
  2738 
       
  2739     "/ for now, only support some depths
       
  2740 
       
  2741     usedDeviceBitsPerPixel == 16 ifTrue:[
       
  2742 	imageBits := ByteArray uninitializedNew:(width * height * 2).
       
  2743 
       
  2744 	"/ now, walk over the image and replace
       
  2745 	"/ colorMap indices by color values in the bits array
       
  2746 
       
  2747 	destIndex := 1.
       
  2748 	0 to:height-1 do:[:y |
       
  2749 	    0 to:width-1 do:[:x |
       
  2750 		|greyValue|
       
  2751 
       
  2752 		greyValue := self valueAtX:x y:y.
       
  2753 		imageBits wordAt:destIndex put:(colorValues at:greyValue + 1) MSB:true.
       
  2754 		destIndex := destIndex + 2.
       
  2755 	    ]
       
  2756 	]
       
  2757     ] ifFalse:[
       
  2758 	usedDeviceBitsPerPixel == 32 ifTrue:[
       
  2759 	    imageBits := ByteArray uninitializedNew:(width * height * 4).
       
  2760 
       
  2761 	    "/ now, walk over the image and replace
       
  2762 	    "/ colorMap indices by color values in the bits array
       
  2763 
       
  2764 	    destIndex := 1.
       
  2765 	    0 to:height-1 do:[:y |
       
  2766 		0 to:width-1 do:[:x |
       
  2767 		    |greyValue|
       
  2768 
       
  2769 		    greyValue := self valueAtX:x y:y.
       
  2770 		    imageBits doubleWordAt:destIndex put:(colorValues at:greyValue + 1) MSB:true.
       
  2771 		    destIndex := destIndex + 4.
       
  2772 		]
       
  2773 	    ]
       
  2774 	]
       
  2775     ].
       
  2776 
       
  2777     imageBits isNil ifTrue:[            
       
  2778 	'IMAGE: unimplemented trueColor depth on greyImageAsTrueColorFormOn:' errorPrintNL.
       
  2779 	^ self paletteImageAsMonoFormOn:aDevice
       
  2780     ].
       
  2781 
       
  2782     form :=
       
  2783     form := Form width:width height:height depth:usedDeviceDepth on:aDevice.
       
  2784     form isNil ifTrue:[^ nil].
       
  2785     form initGC.
       
  2786 
       
  2787     form 
       
  2788 	copyBitsFrom:imageBits bitsPerPixel:usedDeviceBitsPerPixel depth:usedDeviceDepth 
       
  2789 	       width:width height:height 
       
  2790 		   x:0 y:0 toX:0 y:0. 
       
  2791 
       
  2792     ^ form
       
  2793 
       
  2794     "Created: 20.10.1995 / 22:05:10 / cg"
       
  2795     "Modified: 21.10.1995 / 19:30:37 / cg"
  2216 ! !
  2796 ! !
  2217 
  2797 
  2218 !Image methodsFor:'image manipulations'!
  2798 !Image methodsFor:'image manipulations'!
  2219 
  2799 
  2220 copyWithColorMapProcessing:aBlock
  2800 copyWithColorMapProcessing:aBlock
  2698 
  3278 
  2699     "magnify a single pixel row - can only magnify by integer factors,
  3279     "magnify a single pixel row - can only magnify by integer factors,
  2700      can only magnify 1,2,4,8 and 24 bit-per-pixel images. But this is done fast."
  3280      can only magnify 1,2,4,8 and 24 bit-per-pixel images. But this is done fast."
  2701 
  3281 
  2702     ^ self subclassResponsibility
  3282     ^ self subclassResponsibility
       
  3283 !
       
  3284 
       
  3285 bestSupportedImageFormatFor:aDevice
       
  3286     "scan through the image formats as supported by aDevice,
       
  3287      and return the best to use when the receiver is to be represented
       
  3288      on it. The best format is the one with the same number or more bits per
       
  3289      pixel. Here, the smallest format found is taken."
       
  3290 
       
  3291     |bestDeviceDepth bestDeviceBitsPerPixel myDepth maxDepth maxBitsPerPixel|
       
  3292 
       
  3293     myDepth := self bitsPerPixel.
       
  3294     maxBitsPerPixel := 0.
       
  3295 
       
  3296     aDevice supportedImageFormats do:[:entry |
       
  3297 	|deviceImageDepth deviceImageBitsPerPixel|
       
  3298 
       
  3299 	deviceImageDepth := entry at:1.
       
  3300 	deviceImageBitsPerPixel := entry at:2.
       
  3301 	deviceImageBitsPerPixel > maxBitsPerPixel ifTrue:[
       
  3302 	    maxBitsPerPixel := deviceImageBitsPerPixel.
       
  3303 	    maxDepth := deviceImageDepth.
       
  3304 	].
       
  3305 	deviceImageDepth >= myDepth ifTrue:[
       
  3306 	    deviceImageDepth == myDepth ifTrue:[
       
  3307 		"/ take the better one ...
       
  3308 		(bestDeviceDepth isNil
       
  3309 		 or:[(bestDeviceBitsPerPixel ~~ bestDeviceDepth)
       
  3310 		    and:[deviceImageDepth == deviceImageBitsPerPixel]]) ifTrue:[
       
  3311 		    bestDeviceDepth := deviceImageDepth.
       
  3312 		    bestDeviceBitsPerPixel := deviceImageBitsPerPixel.
       
  3313 		]
       
  3314 	    ] ifFalse:[
       
  3315 		"/ take the next-larger depth
       
  3316 		(bestDeviceDepth isNil
       
  3317 		 or:[deviceImageBitsPerPixel < bestDeviceBitsPerPixel]) ifTrue:[
       
  3318 		    bestDeviceDepth := deviceImageDepth.
       
  3319 		    bestDeviceBitsPerPixel := deviceImageBitsPerPixel.
       
  3320 		]
       
  3321 	    ]    
       
  3322 	].
       
  3323     ].
       
  3324     bestDeviceDepth isNil ifTrue:[
       
  3325 	maxBitsPerPixel == 0 ifTrue:[
       
  3326 	    bestDeviceDepth := bestDeviceBitsPerPixel := aDevice depth.
       
  3327 	] ifFalse:[
       
  3328 	    bestDeviceDepth := maxDepth.
       
  3329 	    bestDeviceBitsPerPixel := maxBitsPerPixel
       
  3330 	]
       
  3331     ].
       
  3332     ^ Array with:bestDeviceDepth with:bestDeviceBitsPerPixel
       
  3333 
       
  3334     "Created: 21.10.1995 / 02:17:48 / cg"
       
  3335     "Modified: 21.10.1995 / 03:52:45 / cg"
  2703 ! !
  3336 ! !
  2704 
  3337 
  2705 !Image methodsFor: 'binary storage'!
  3338 !Image methodsFor: 'binary storage'!
  2706 
  3339 
  2707 storeBinaryDefinitionOn: stream manager: manager
  3340 storeBinaryDefinitionOn: stream manager: manager