1214 depth := image depth. |
1214 depth := image depth. |
1215 width := image width. |
1215 width := image width. |
1216 height := image height. |
1216 height := image height. |
1217 |
1217 |
1218 depth ~~ 4 ifTrue:[ |
1218 depth ~~ 4 ifTrue:[ |
1219 ^ Image cannotRepresentImageSignal |
1219 ^ Image cannotRepresentImageSignal |
1220 raiseWith:image |
1220 raiseWith:image |
1221 errorString:('ICO format only supports depths 4'). |
1221 errorString:('ICO format only supports depths 4'). |
1222 ]. |
1222 ]. |
1223 (width ~~ 32 or:[height ~~ 32]) ifTrue:[ |
1223 (width ~~ 32 or:[height ~~ 32]) ifTrue:[ |
1224 ^ Image cannotRepresentImageSignal |
1224 ^ Image cannotRepresentImageSignal |
1225 raiseWith:image |
1225 raiseWith:image |
1226 errorString:('ICO format (currently) only supports 32x32 bitmaps'). |
1226 errorString:('ICO format (currently) only supports 32x32 bitmaps'). |
1227 ]. |
1227 ]. |
1228 |
1228 |
1229 "/ align rows on a longword boundary |
1229 "/ align rows on a longword boundary |
1230 rowBytes := (depth * width + 31 // 32) * 4. |
1230 rowBytes := ((depth * width + 31) // 32) * 4. |
1231 biSizeImage := height * rowBytes. |
1231 biSizeImage := height * rowBytes. |
1232 |
1232 |
1233 outStream := fileName asFilename writeStream. |
1233 outStream := fileName asFilename writeStream. |
1234 outStream binary. |
1234 outStream binary. |
1235 byteOrder := #lsb. |
1235 byteOrder := #lsb. |
1248 outStream nextPutAll:(ByteArray new:40). |
1248 outStream nextPutAll:(ByteArray new:40). |
1249 |
1249 |
1250 "/ 16-entry RGB map |
1250 "/ 16-entry RGB map |
1251 |
1251 |
1252 1 to:16 do:[:i | "Color map" |
1252 1 to:16 do:[:i | "Color map" |
1253 |clr r g b| |
1253 |clr r g b| |
1254 |
1254 |
1255 clr := image colorFromValue:i-1. |
1255 clr := image colorFromValue:i-1. |
1256 clr isNil ifTrue:[ |
1256 clr isNil ifTrue:[ |
1257 r := g := b := 0. |
1257 r := g := b := 0. |
1258 ] ifFalse:[ |
1258 ] ifFalse:[ |
1259 r := clr redByte. |
1259 r := clr redByte. |
1260 g := clr greenByte. |
1260 g := clr greenByte. |
1261 b := clr blueByte. |
1261 b := clr blueByte. |
1262 ]. |
1262 ]. |
1263 |
1263 |
1264 "/ put B,G,R |
1264 "/ put B,G,R |
1265 outStream nextPut:b. |
1265 outStream nextPut:b. |
1266 outStream nextPut:g. |
1266 outStream nextPut:g. |
1267 outStream nextPut:r. |
1267 outStream nextPut:r. |
1268 outStream nextPut:0. |
1268 outStream nextPut:0. |
1269 ]. |
1269 ]. |
1270 |
1270 |
1271 imgBytesPerRow := image bytesPerRow. |
1271 imgBytesPerRow := image bytesPerRow. |
1272 data := image data. |
1272 data := image bits. |
1273 |
1273 |
1274 |
1274 |
1275 "/ sorry, must extract rows individually |
1275 "/ sorry, must extract rows individually |
1276 "/ (even if alignment is correct), |
1276 "/ (even if alignment is correct), |
1277 "/ since ICO saves rows bottom-to-top |
1277 "/ since ICO saves rows bottom-to-top |
1278 |
1278 |
1279 row := ByteArray new:rowBytes. |
1279 row := ByteArray new:rowBytes. |
1280 |
1280 |
1281 srcIndex := 1 + (height * imgBytesPerRow). |
1281 srcIndex := 1 + (height * imgBytesPerRow). |
1282 1 to:height do:[:i | |
1282 1 to:height do:[:i | |
1283 srcIndex := srcIndex - imgBytesPerRow. |
1283 srcIndex := srcIndex - imgBytesPerRow. |
1284 row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex. |
1284 row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex. |
1285 outStream nextPutAll:row. |
1285 outStream nextPutAll:row. |
1286 ]. |
1286 ]. |
1287 |
1287 |
1288 "/ the mask ... |
1288 "/ the mask ... |
1289 image mask isNil ifTrue:[ |
1289 image mask isNil ifTrue:[ |
1290 outStream next:128 put:16rFF |
1290 outStream next:128 put:16rFF |
1291 ] ifFalse:[ |
1291 ] ifFalse:[ |
1292 imgBytesPerRow := image mask bytesPerRow. |
1292 imgBytesPerRow := image mask bytesPerRow. |
1293 data := image mask data. |
1293 data := image mask data. |
1294 row := ByteArray new:4. |
1294 row := ByteArray new:4. |
1295 |
1295 |
1296 srcIndex := 1 + (height * imgBytesPerRow). |
1296 srcIndex := 1 + (height * imgBytesPerRow). |
1297 1 to:height do:[:i | |
1297 1 to:height do:[:i | |
1298 srcIndex := srcIndex - imgBytesPerRow. |
1298 srcIndex := srcIndex - imgBytesPerRow. |
1299 row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex. |
1299 row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex. |
1300 outStream nextPutAll:row. |
1300 outStream nextPutAll:row. |
1301 ]. |
1301 ]. |
1302 ]. |
1302 ]. |
1303 |
1303 |
1304 outStream close. |
1304 outStream close. |
1305 |
1305 |
1306 " |
1306 " |