Depth32Image.st
changeset 8327 98509411b62e
parent 8264 a37a81b3942b
child 8339 b2b10047577b
equal deleted inserted replaced
8326:ff1b239ffe17 8327:98509411b62e
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1995 by Claus Gittinger
     2  COPYRIGHT (c) 1995 by Claus Gittinger
     5 	      All Rights Reserved
     3 	      All Rights Reserved
     6 
     4 
     7  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
    43     this class represents 32 bit (eg. rgb+alpha) images.
    41     this class represents 32 bit (eg. rgb+alpha) images.
    44 
    42 
    45     Only the minimum protocol is implemented here; much more is
    43     Only the minimum protocol is implemented here; much more is
    46     needed for higher performance operations on depth32 images.
    44     needed for higher performance operations on depth32 images.
    47 
    45 
    48     Sometimes, 32bit images with no alpha information (i.e. r,g,b,0) is encountered.
    46     with #rgb, #rgba, #rgbx, photometrics 
    49     In this case, we treat the low byte as red, the next as green, the 2rd as blue byte,
    47     pixels are internally stored byte-wise in rgba order.
    50     and ignore the fourth byte.
    48     (i.e. r at low-address byte, a at high-address byte). 
    51     When reading/writing pixel values, these are treated like argb (i.e. the blue bits are in low bit positions,
    49     For rgb, a zero is always retrieved as alpha; 255 for rgbx.
    52     not shifted).
    50 
    53     
    51     When reading pixel values, photometric argb is returned as aarrggbb,
       
    52     photometric rgb is returned as 00rrggbb,
       
    53     photometric rgba is returned as rrggbb00,
       
    54     both on LSB and on MSB machines.
       
    55     (i.e. blue in lower bits of the returned 32bit integer, alpha in the high bits for argb,
       
    56      and in the low bits for rgba)
       
    57     Thus, pixelValues and rgbValues are identical, simulating MSB on all
       
    58     architectures.
       
    59     (this should be transparent, if you use the rgbValueAt
       
    60      accessors; however, some old code uses pixelValueAt:, assuming that the
       
    61     returned pixel value is rrggbb - which it would not be without this hack).
       
    62 
       
    63     This also makes depth24Image's rgbValues compatible with depth32Image's rgbValues.
       
    64 
       
    65     For argb and xrgb formats, alpha (or dummy alpha) is in the first byte 
       
    66     (which are the high bits, as we present pixel values always MSB).
       
    67 
    54     [author:]
    68     [author:]
    55         Claus Gittinger
    69         Claus Gittinger
    56 
    70 
    57     [see also:]
    71     [see also:]
    58         Depth1Image Depth2Image Depth4Image Depth8Image Depth16Image Depth24Image
    72         Depth1Image Depth2Image Depth4Image Depth8Image Depth16Image Depth24Image
    96 
   110 
    97     |index "{ Class: SmallInteger }"
   111     |index "{ Class: SmallInteger }"
    98      rVal gVal bVal aVal|
   112      rVal gVal bVal aVal|
    99 
   113 
   100     index := 1 + (((width * y) + x) * 4).
   114     index := 1 + (((width * y) + x) * 4).
   101     ((photometric == #rgb) or:[ photometric == #xrgb]) ifTrue:[
   115     (photometric == #rgb) ifTrue:[
   102         "/ is: ignore,r,g,b
   116         "/ byteorder is: r,g,b,<ignoredAlpha>
   103         rVal := bytes at:(index + 1).
   117         rVal := bytes at:(index).
   104         gVal := bytes at:(index + 2).
   118         gVal := bytes at:(index + 1).
   105         bVal := bytes at:(index + 3).
   119         bVal := bytes at:(index + 2).
   106         ^ Color redByte:rVal greenByte:gVal blueByte:bVal
   120         ^ Color redByte:rVal greenByte:gVal blueByte:bVal
   107     ].
   121     ].
   108     photometric == #rgba ifTrue:[
   122     (photometric == #rgba) ifTrue:[
       
   123         "/ byteorder is: r,g,b,<ignoredAlpha>
   109         rVal := bytes at:(index).
   124         rVal := bytes at:(index).
   110         gVal := bytes at:(index + 1).
   125         gVal := bytes at:(index + 1).
   111         bVal := bytes at:(index + 2).
   126         bVal := bytes at:(index + 2).
   112         aVal := bytes at:(index + 3).
   127         aVal := bytes at:(index + 3).
   113         ^ Color redByte:rVal greenByte:gVal blueByte:bVal alphaByte:aVal
   128         ^ Color redByte:rVal greenByte:gVal blueByte:bVal alphaByte:aVal
   114     ].
   129     ].
   115     photometric == #argb ifTrue:[
   130     photometric == #argb ifTrue:[
       
   131         "/ byteorder is: a,r,g,b
   116         aVal := bytes at:(index).
   132         aVal := bytes at:(index).
   117         rVal := bytes at:(index + 1).
   133         rVal := bytes at:(index + 1).
   118         gVal := bytes at:(index + 2).
   134         gVal := bytes at:(index + 2).
   119         bVal := bytes at:(index + 3).
   135         bVal := bytes at:(index + 3).
   120         ^ Color redByte:rVal greenByte:gVal blueByte:bVal alphaByte:aVal
   136         ^ Color redByte:rVal greenByte:gVal blueByte:bVal alphaByte:aVal
   121     ].
   137     ].
   122 
       
   123     "/ the inherited method should handle all cases.
   138     "/ the inherited method should handle all cases.
   124     ^ super colorAtX:x y:y.
   139     ^ super colorAtX:x y:y.
   125 
   140 
   126     "Modified: / 22-08-2017 / 18:17:38 / cg"
   141     "Modified: / 22-08-2017 / 18:17:38 / cg"
   127 !
   142 !
   138     r := aColor redByte.
   153     r := aColor redByte.
   139     g := aColor greenByte.
   154     g := aColor greenByte.
   140     b := aColor blueByte.
   155     b := aColor blueByte.
   141     
   156     
   142     (photometric == #rgb) ifTrue:[
   157     (photometric == #rgb) ifTrue:[
   143         "/ is: ignore,r,g,b
   158         "/ byteorder is: r,g,b
   144         bytes at:(index + 0) put:0.              
   159         bytes at:(index) put:r.
   145         bytes at:(index + 1) put:r.
   160         bytes at:(index + 1) put:g.
   146         bytes at:(index + 2) put:g.
   161         bytes at:(index + 2) put:b.
   147         bytes at:(index + 3) put:b.
       
   148         ^ self
   162         ^ self
   149     ].
   163     ].
   150     (photometric == #xrgb) ifTrue:[
       
   151         bytes at:(index + 0) put:255.              
       
   152         bytes at:(index + 1) put:r.
       
   153         bytes at:(index + 2) put:g.
       
   154         bytes at:(index + 3) put:b.
       
   155         ^ self
       
   156     ].
       
   157     (photometric == #rgba) ifTrue:[
   164     (photometric == #rgba) ifTrue:[
       
   165         "/ byteorder is: r,g,b,a
   158         bytes at:(index + 0) put:r.
   166         bytes at:(index + 0) put:r.
   159         bytes at:(index + 1) put:g.
   167         bytes at:(index + 1) put:g.
   160         bytes at:(index + 2) put:b.
   168         bytes at:(index + 2) put:b.
   161         bytes at:(index + 3) put:(aColor alphaByte). "alpha channel in last byte"
   169         bytes at:(index + 3) put:(aColor alphaByte). "alpha channel in last byte"
   162         ^ self
   170         ^ self
   163     ].
   171     ].
   164     (photometric == #argb) ifTrue:[
   172     (photometric == #argb) ifTrue:[
       
   173         "/ byteorder is: a,r,g,b
   165         bytes at:(index + 0) put:(aColor alphaByte).     "alpha channel in first byte"
   174         bytes at:(index + 0) put:(aColor alphaByte).     "alpha channel in first byte"
   166         bytes at:(index + 1) put:r.
   175         bytes at:(index + 1) put:r.
   167         bytes at:(index + 2) put:g.
   176         bytes at:(index + 2) put:g.
   168         bytes at:(index + 3) put:b.             
   177         bytes at:(index + 3) put:b.             
       
   178         ^ self
       
   179     ].
       
   180     (photometric == #xrgb) ifTrue:[
       
   181         "/ byteorder is: <ignoredAlpha>,r,g,b
       
   182         bytes at:(index + 1) put:r.
       
   183         bytes at:(index + 2) put:g.
       
   184         bytes at:(index + 3) put:b.
       
   185         ^ self
       
   186     ].
       
   187     (photometric == #rgbx) ifTrue:[
       
   188         "/ byteorder is: <ignoredAlpha>,r,g,b
       
   189         bytes at:(index) put:r.
       
   190         bytes at:(index + 1) put:g.
       
   191         bytes at:(index + 2) put:b.
   169         ^ self
   192         ^ self
   170     ].
   193     ].
   171 
   194 
   172     super colorAtX:x y:y put:aColor.
   195     super colorAtX:x y:y put:aColor.
   173 
   196 
   178     "retrieve a pixel at x/y; return a pixelValue.
   201     "retrieve a pixel at x/y; return a pixelValue.
   179      The interpretation of the returned value depends on the photometric
   202      The interpretation of the returned value depends on the photometric
   180      and the colormap. See also Image>>atX:y:)
   203      and the colormap. See also Image>>atX:y:)
   181      Pixels start at x=0 , y=0 for upper left pixel, end at
   204      Pixels start at x=0 , y=0 for upper left pixel, end at
   182      x = width-1, y=height-1 for lower right pixel.
   205      x = width-1, y=height-1 for lower right pixel.
   183      With rgba photometric, the pixel value contains r/g/b/a in msb order (i.e. r at high, a at low bits);
   206      With rgba photometric, the pixel value contains r/g/b/a in lsb order 
   184      with argb, alpha is in the high byte"
   207      (i.e. r at low, a at high bits);
       
   208      with argb, alpha is in the low byte"
   185 
   209 
   186     |pixelIndex "{ Class: SmallInteger }"|
   210     |pixelIndex "{ Class: SmallInteger }"|
   187 
   211 
   188 %{  /* NOCONTEXT */
   212 %{  /* NOCONTEXT */
   189     OBJ b = __INST(bytes);
   213     OBJ b = __INST(bytes);
   229 
   253 
   230 pixelAtX:x y:y put:aPixelValue
   254 pixelAtX:x y:y put:aPixelValue
   231     "set the pixel at x/y to aPixelValue.
   255     "set the pixel at x/y to aPixelValue.
   232      The interpretation of the pixelValue depends on the photometric.
   256      The interpretation of the pixelValue depends on the photometric.
   233      Pixels start at x=0 , y=0 for upper left pixel, end at
   257      Pixels start at x=0 , y=0 for upper left pixel, end at
   234      x = width-1, y=height-1 for lower right pixel"
   258      x = width-1, y=height-1 for lower right pixel.
       
   259      With rgba photometric, the pixel value contains r/g/b/a in lsb order 
       
   260      (i.e. r at low, a at high bits);
       
   261      with argb, alpha is in the low byte"
   235 
   262 
   236     |pixelIndex "{ Class: SmallInteger }"|
   263     |pixelIndex "{ Class: SmallInteger }"|
   237 
   264 
   238 %{  /* NOCONTEXT */
   265 %{  /* NOCONTEXT */
   239     OBJ b = __INST(bytes);
   266     OBJ b = __INST(bytes);
   272     "Modified: / 22-08-2017 / 18:21:47 / cg"
   299     "Modified: / 22-08-2017 / 18:21:47 / cg"
   273 !
   300 !
   274 
   301 
   275 rowAt:y putAll:pixelArray startingAt:startIndex
   302 rowAt:y putAll:pixelArray startingAt:startIndex
   276     "store a single rows bits from bits in the pixelArray argument;
   303     "store a single rows bits from bits in the pixelArray argument;
   277      Return the pixelArray.
   304      The interpretation of the pixel values depends on the photometric.
   278      Notice: row coordinate starts at 0."
   305      Notice: row coordinate starts at 0."
   279 
   306 
   280     |bytes pixel
   307     |bytes pixel
   281      dstIdx "{ Class: SmallInteger }" 
   308      dstIdx "{ Class: SmallInteger }" 
   282      w "{ Class: SmallInteger }"|
   309      w "{ Class: SmallInteger }"|
   285     dstIdx := (y * self bytesPerRow) + 1.
   312     dstIdx := (y * self bytesPerRow) + 1.
   286     w := width - 1.
   313     w := width - 1.
   287 
   314 
   288     0 to:w do:[:col |
   315     0 to:w do:[:col |
   289         pixel := pixelArray at:(startIndex + col).
   316         pixel := pixelArray at:(startIndex + col).
       
   317         "/ msbFirst
   290         bytes unsignedInt32At:dstIdx put:pixel MSB:true.
   318         bytes unsignedInt32At:dstIdx put:pixel MSB:true.
   291         dstIdx := dstIdx + 4.
   319         dstIdx := dstIdx + 4.
   292     ].
   320     ].
   293     ^ pixelArray
       
   294 
   321 
   295     "Modified (comment): / 21-02-2017 / 15:03:24 / cg"
   322     "Modified (comment): / 21-02-2017 / 15:03:24 / cg"
   296 ! !
   323 ! !
   297 
   324 
   298 !Depth32Image methodsFor:'converting rgb images'!
   325 !Depth32Image methodsFor:'converting rgb images'!
   836 !Depth32Image methodsFor:'image manipulations'!
   863 !Depth32Image methodsFor:'image manipulations'!
   837 
   864 
   838 negative
   865 negative
   839     |bytes 
   866     |bytes 
   840      index "{ Class: SmallInteger }"
   867      index "{ Class: SmallInteger }"
   841      newImage newBytes nBytes r g b a|
   868      newImage newBytes nBytes r g b a
   842 
   869      alphaFirst|
   843     photometric ~~ #rgb ifTrue:[
   870 
       
   871     ((photometric ~~ #argb)
       
   872     and:[(photometric ~~ #rgba)
       
   873     and:[(photometric ~~ #xrgb)
       
   874     and:[(photometric ~~ #rgbx)
       
   875     and:[(photometric ~~ #rgb0)
       
   876     and:[(photometric ~~ #'0rgb')]]]]]) ifTrue:[
   844         ^ super negative.
   877         ^ super negative.
   845     ].
   878     ].
       
   879 
       
   880     alphaFirst := (photometric == #argb)
       
   881                   or:[ (photometric == #xrgb) 
       
   882                   or:[ (photometric == #'0rgb') ]].
       
   883 
   846     bytes := self bits.
   884     bytes := self bits.
   847 
   885 
   848     newImage := self copy.
   886     newImage := self copy.
   849     nBytes := bytes size.
   887     nBytes := bytes size.
   850     newImage bits:(newBytes := ByteArray new:nBytes).
   888     newImage bits:(newBytes := ByteArray new:nBytes).
   851     index := 1.
   889     index := 1.
   852     [index < nBytes] whileTrue:[
   890     [index < nBytes] whileTrue:[
       
   891         alphaFirst ifTrue:[
       
   892             a := bytes at:index.
       
   893             newBytes at:index put:a.
       
   894             index := index + 1.
       
   895         ].
       
   896 
   853         r := bytes at:index.
   897         r := bytes at:index.
   854         newBytes at:index put:(255-r).
   898         newBytes at:index put:(255-r).
   855         index := index + 1.
   899         index := index + 1.
   856         
   900         
   857         g := bytes at:index.
   901         g := bytes at:index.
   860 
   904 
   861         b := bytes at:index.
   905         b := bytes at:index.
   862         newBytes at:index put:(255-b).
   906         newBytes at:index put:(255-b).
   863         index := index + 1.
   907         index := index + 1.
   864 
   908 
   865         a := bytes at:index.
   909         alphaFirst ifFalse:[
   866         newBytes at:index put:a.
   910             a := bytes at:index.
   867         index := index + 1.
   911             newBytes at:index put:a.
       
   912             index := index + 1.
       
   913         ]
   868     ].
   914     ].
   869     ^ newImage
   915     ^ newImage
   870 
   916 
   871     "Modified (format): / 22-08-2017 / 17:13:38 / cg"
   917     "Modified (format): / 22-08-2017 / 17:13:38 / cg"
   872 ! !
   918 ! !
  1111 
  1157 
  1112 alphaBitsOf:pixel
  1158 alphaBitsOf:pixel
  1113     "given a pixel-value, return the alpha component as byteValue (0..255)"
  1159     "given a pixel-value, return the alpha component as byteValue (0..255)"
  1114 
  1160 
  1115     photometric == #argb ifTrue:[
  1161     photometric == #argb ifTrue:[
  1116         "a,r,g,b; MSB"
  1162         "/ value is: aarrggbb
  1117         ^ (pixel bitShift:-24) bitAnd:16rFF.
  1163         ^ (pixel bitShift:-24) bitAnd:16rFF.   
       
  1164     ].
       
  1165     (photometric == #rgb) ifTrue:[
       
  1166         "/ value is: 00rrggbb
       
  1167         ^ 0
       
  1168     ].
       
  1169     (photometric == #xrgb) ifTrue:[
       
  1170         "/ value is: FFrrggbb
       
  1171         ^ 255       
  1118     ].
  1172     ].
  1119     photometric == #rgba ifTrue:[
  1173     photometric == #rgba ifTrue:[
  1120         "r,g,b,a; MSB"
  1174         "/ value is: rrggbbaa
  1121         ^ pixel bitAnd:16rFF.
  1175         ^ pixel bitAnd:16rFF           
  1122     ].
  1176     ].
  1123     "r,g,b,0; MSB"
  1177     photometric == #rgb0 ifTrue:[
  1124     ^ 0
  1178         "/ value is: rrggbb00
       
  1179         ^ 0           
       
  1180     ].
       
  1181     photometric == #rgbx ifTrue:[
       
  1182         "/ value is: rrggbbFF
       
  1183         ^ 255           
       
  1184     ].
       
  1185 
       
  1186     ^ super alphaBitsOf:pixel.
  1125 
  1187 
  1126     "Modified: / 22-08-2017 / 17:18:44 / cg"
  1188     "Modified: / 22-08-2017 / 17:18:44 / cg"
  1127 !
  1189 !
  1128 
  1190 
  1129 alphaComponentOf:pixel
  1191 alphaComponentOf:pixel
  1143 
  1205 
  1144 alphaShiftForPixelValue
  1206 alphaShiftForPixelValue
  1145     "return the shift amount used with translation from pixelValues to alphaBits.
  1207     "return the shift amount used with translation from pixelValues to alphaBits.
  1146      That is the number of bits to shift the alpha value into the pixel value."
  1208      That is the number of bits to shift the alpha value into the pixel value."
  1147 
  1209 
  1148     photometric == #argb ifTrue:[
  1210     ((photometric == #argb)
  1149         "/ a,r,g,b - alpha in high byte
  1211     or:[ (photometric == #rgb) 
  1150         ^ 24.
  1212     or:[ (photometric == #xrgb) ]])
  1151     ].
  1213      ifTrue:[
  1152     "/ r,g,b,a - alpha in low byte 
  1214         "/ aarrggbb
  1153     "/ or r,g,b,0 - no alpha
  1215         ^ -24.    
  1154     ^ 0
  1216     ].
       
  1217     ((photometric == #rgba) 
       
  1218     or:[ (photometric == #rgbx) 
       
  1219     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1220         "/ rrggbbaa
       
  1221         ^ 0.    
       
  1222     ].
       
  1223     ^ super alphaShiftForPixelValue.
  1155 
  1224 
  1156     "Modified: / 22-08-2017 / 17:19:36 / cg"
  1225     "Modified: / 22-08-2017 / 17:19:36 / cg"
  1157 !
  1226 !
  1158 
  1227 
  1159 bitsPerPixel
  1228 bitsPerPixel
  1183 !
  1252 !
  1184 
  1253 
  1185 blueBitsOf:pixel
  1254 blueBitsOf:pixel
  1186     "given a pixel-value, return the blue component as byteValue (0..255)"
  1255     "given a pixel-value, return the blue component as byteValue (0..255)"
  1187 
  1256 
  1188     photometric == #rgba ifTrue:[
  1257     ((photometric == #argb)
  1189         ^ (pixel bitShift:-8) bitAnd:16rFF.
  1258     or:[ (photometric == #rgb) 
  1190     ].
  1259     or:[ (photometric == #xrgb) ]])
  1191     "r,g,b,a or ignored,r,g,b"
  1260      ifTrue:[
  1192     ^ pixel bitAnd:16rFF.
  1261         "/ aarrggbb
       
  1262         ^ pixel bitAnd:16rFF.    
       
  1263     ].
       
  1264     ((photometric == #rgba) 
       
  1265     or:[ (photometric == #rgbx) 
       
  1266     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1267         "/ rrggbbaa
       
  1268         ^ (pixel bitShift:-8) bitAnd:16rFF.    
       
  1269     ].
       
  1270     ^ super blueBitsOf:pixel.
  1193 
  1271 
  1194     "Modified: / 22-08-2017 / 18:23:41 / cg"
  1272     "Modified: / 22-08-2017 / 18:23:41 / cg"
  1195 !
  1273 !
  1196 
  1274 
  1197 blueComponentOf:pixel
  1275 blueComponentOf:pixel
  1207 !
  1285 !
  1208 
  1286 
  1209 blueShiftForPixelValue
  1287 blueShiftForPixelValue
  1210     "return the shift amount used with translation from pixelValues to blueBits"
  1288     "return the shift amount used with translation from pixelValues to blueBits"
  1211 
  1289 
  1212     photometric == #argb ifTrue:[
  1290     ((photometric == #argb)
  1213         "a,r,g,b"
  1291     or:[ (photometric == #rgb) 
  1214         ^ 0.
  1292     or:[ (photometric == #xrgb) ]])
  1215     ].
  1293      ifTrue:[
  1216     "r,g,b,a or r,g,b,0"
  1294         "/ aarrggbb
  1217     ^ -8
  1295         ^ 0.    
       
  1296     ].
       
  1297     ((photometric == #rgba) 
       
  1298     or:[ (photometric == #rgbx) 
       
  1299     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1300         "/ rrggbbaa
       
  1301         ^ -8
       
  1302     ].
       
  1303     ^ super blueShiftForPixelValue
  1218 
  1304 
  1219     "Modified: / 22-08-2017 / 17:19:55 / cg"
  1305     "Modified: / 22-08-2017 / 17:19:55 / cg"
  1220 !
  1306 !
  1221 
  1307 
  1222 bytesPerRow
  1308 bytesPerRow
  1228 !
  1314 !
  1229 
  1315 
  1230 greenBitsOf:pixel
  1316 greenBitsOf:pixel
  1231     "given a pixel-value, return the green component as byteValue (0..255)"
  1317     "given a pixel-value, return the green component as byteValue (0..255)"
  1232 
  1318 
  1233     photometric == #rgba ifTrue:[
  1319     ((photometric == #argb)
  1234         ^ (pixel bitShift:-16) bitAnd:16rFF.
  1320     or:[ (photometric == #rgb) 
  1235     ].
  1321     or:[ (photometric == #xrgb) ]])
  1236     ^ (pixel bitShift:-8) bitAnd:16rFF.
  1322      ifTrue:[
  1237 
  1323         "/ aarrggbb
  1238     "Modified: / 22-08-2017 / 18:25:26 / cg"
  1324         ^ (pixel bitShift:-8) bitAnd:16rFF.    
       
  1325     ].
       
  1326     ((photometric == #rgba) 
       
  1327     or:[ (photometric == #rgbx) 
       
  1328     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1329         "/ rrggbbaa
       
  1330         ^ (pixel bitShift:-16) bitAnd:16rFF.    
       
  1331     ].
       
  1332     ^ super greenBitsOf:pixel.
       
  1333 
       
  1334     "Modified: / 22-08-2017 / 18:23:41 / cg"
  1239 !
  1335 !
  1240 
  1336 
  1241 greenComponentOf:pixel
  1337 greenComponentOf:pixel
  1242     "given a pixel-value, return the green component in percent (0..100)"
  1338     "given a pixel-value, return the green component in percent (0..100)"
  1243 
  1339 
  1251 !
  1347 !
  1252 
  1348 
  1253 greenShiftForPixelValue
  1349 greenShiftForPixelValue
  1254     "return the shift amount used with translation from pixelValues to greenBits"
  1350     "return the shift amount used with translation from pixelValues to greenBits"
  1255 
  1351 
  1256     photometric == #argb ifTrue:[
  1352     ((photometric == #argb)
  1257         "a,r,g,b"
  1353     or:[ (photometric == #rgb) 
  1258         ^ -8.
  1354     or:[ (photometric == #xrgb) ]])
  1259     ].
  1355      ifTrue:[
  1260     "r,g,b,a or r,g,b,0"
  1356         "/ aarrggbb
  1261     ^ -16
  1357         ^ -8    
  1262 
  1358     ].
  1263     "Modified: / 22-08-2017 / 17:20:14 / cg"
  1359     ((photometric == #rgba) 
       
  1360     or:[ (photometric == #rgbx) 
       
  1361     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1362         "/ rrggbbaa
       
  1363         ^ -16.    
       
  1364     ].
       
  1365     ^ super greenShiftForPixelValue.
  1264 !
  1366 !
  1265 
  1367 
  1266 hasAlphaChannel
  1368 hasAlphaChannel
  1267     "could be #rgb in 32 bits..."
  1369     "could be #rgb in 32 bits..."
  1268 
  1370 
  1302 !
  1404 !
  1303 
  1405 
  1304 redBitsOf:pixel
  1406 redBitsOf:pixel
  1305     "given a pixel-value, return the red component as byteValue (0..255)"
  1407     "given a pixel-value, return the red component as byteValue (0..255)"
  1306 
  1408 
  1307     photometric == #rgba ifTrue:[
  1409     ((photometric == #argb)
  1308         ^ (pixel bitShift:-24) bitAnd:16rFF.
  1410     or:[ (photometric == #rgb) 
  1309     ].
  1411     or:[ (photometric == #xrgb) ]])
  1310     ^ (pixel bitShift:-16) bitAnd:16rFF.
  1412      ifTrue:[
  1311 
  1413         "/ aarrggbb
  1312     "Modified: / 22-08-2017 / 18:25:52 / cg"
  1414         ^ (pixel bitShift:-16) bitAnd:16rFF.    
       
  1415     ].
       
  1416     ((photometric == #rgba) 
       
  1417     or:[ (photometric == #rgbx) 
       
  1418     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1419         "/ rrggbbaa
       
  1420         ^ (pixel bitShift:-24) bitAnd:16rFF.    
       
  1421     ].
       
  1422     ^ super redBitsOf:pixel.
       
  1423 
       
  1424     "Modified: / 22-08-2017 / 18:23:41 / cg"
  1313 !
  1425 !
  1314 
  1426 
  1315 redComponentOf:pixel
  1427 redComponentOf:pixel
  1316     "given a pixel-value, return the red component in percent (0..100)"
  1428     "given a pixel-value, return the red component in percent (0..100)"
  1317 
  1429 
  1325 !
  1437 !
  1326 
  1438 
  1327 redShiftForPixelValue
  1439 redShiftForPixelValue
  1328     "return the shift amount used with translation from pixelValues to redBits"
  1440     "return the shift amount used with translation from pixelValues to redBits"
  1329 
  1441 
  1330     photometric == #rgba ifTrue:[
  1442     ((photometric == #argb)
  1331         ^ -24.
  1443     or:[ (photometric == #rgb) 
  1332     ].
  1444     or:[ (photometric == #xrgb) ]])
  1333     ^ -16
  1445      ifTrue:[
  1334 
  1446         "/ aarrggbb
  1335     "Modified: / 22-08-2017 / 18:27:02 / cg"
  1447         ^ -16    
       
  1448     ].
       
  1449     ((photometric == #rgba) 
       
  1450     or:[ (photometric == #rgbx) 
       
  1451     or:[ (photometric == #rgb0)]]) ifTrue:[
       
  1452         "/ rrggbbaa
       
  1453         ^ -24.    
       
  1454     ].
       
  1455     ^ super redShiftForPixelValue.
       
  1456 
       
  1457     "Modified: / 22-08-2017 / 18:23:41 / cg"
  1336 !
  1458 !
  1337 
  1459 
  1338 rgbFromValue:pixelValue
  1460 rgbFromValue:pixelValue
  1339     "given a pixel value, return the corresponding 24bit rgbValue (rrggbb, red is MSB)."
  1461     "given a pixel value, return the corresponding 24bit rgbValue (rrggbb, red is MSB)."
  1340 
  1462 
  1341     (photometric == #rgba) ifTrue:[
  1463     ((photometric == #argb)
  1342         ^ pixelValue rightShift:8     "lsb is alpha channel"
  1464     or:[ (photometric == #rgb) 
  1343     ].
  1465     or:[ (photometric == #xrgb) ]])
  1344     ((photometric == #rgb) or:[photometric == #argb]) ifTrue:[
  1466      ifTrue:[
  1345         ^ pixelValue bitAnd:16rFFFFFF     "msb is alpha channel"
  1467         "/ aarrggbb
       
  1468         ^ pixelValue bitAnd:16rFFFFFF   
       
  1469     ].
       
  1470 
       
  1471     ((photometric == #rgba) 
       
  1472     or:[ photometric == #rgbx
       
  1473     or:[ photometric == #rgb0]]) ifTrue:[
       
  1474         "/ rrggbbaa
       
  1475         ^ (pixelValue rightShift:8) bitAnd:16rFFFFFF       
  1346     ].
  1476     ].
  1347     ^ super rgbFromValue:pixelValue.
  1477     ^ super rgbFromValue:pixelValue.
  1348 
  1478 
  1349     "Modified: / 22-08-2017 / 18:32:22 / cg"
  1479     "Modified: / 22-08-2017 / 18:32:22 / cg"
  1350 !
  1480 !