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:[ |
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 |
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 |