Depth8Image.st
changeset 7407 42d2b51f3c19
parent 7361 ebd5415005b8
child 7424 79d2310a0c43
equal deleted inserted replaced
7406:e35784ee543c 7407:42d2b51f3c19
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1993 by Claus Gittinger
     2  COPYRIGHT (c) 1993 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
   260 
   258 
   261 !Depth8Image methodsFor:'converting images'!
   259 !Depth8Image methodsFor:'converting images'!
   262 
   260 
   263 anyImageAsPseudoFormOn:aDevice
   261 anyImageAsPseudoFormOn:aDevice
   264     "return a pseudoForm from the palette picture.
   262     "return a pseudoForm from the palette picture.
   265      The main work is in color reduction, when not all colors can be aquired.
   263      The main work is in color reduction, when not all colors can be acquired.
   266      This method works for any photometric."
   264      This method works for any photometric."
   267 
   265 
   268     |bytes pseudoBits f gcRound has8BitImage deviceDepth
   266     |bytes pseudoBits f gcRound has8BitImage deviceDepth
   269      imgMap newImage pixelRow dColors
   267      imgMap newImage pixelRow dColors
   270      usedColors usageCounts maxIndex map
   268      usedColors usageCounts maxIndex map
   275      m          "{Class: SmallInteger }"
   273      m          "{Class: SmallInteger }"
   276      mapSize    "{Class: SmallInteger }"
   274      mapSize    "{Class: SmallInteger }"
   277      cube nR nG nB ditherColors clr|
   275      cube nR nG nB ditherColors clr|
   278 
   276 
   279     (cube := aDevice fixColors) notNil ifTrue:[
   277     (cube := aDevice fixColors) notNil ifTrue:[
   280 	nR := aDevice numFixRed.
   278         nR := aDevice numFixRed.
   281 	nG := aDevice numFixGreen.
   279         nG := aDevice numFixGreen.
   282 	nB := aDevice numFixBlue.
   280         nB := aDevice numFixBlue.
   283 
   281 
   284 	DitherAlgorithm == #floydSteinberg ifTrue:[
   282         DitherAlgorithm == #floydSteinberg ifTrue:[
   285 	    f := self
   283             f := self
   286 		   asFloydSteinbergDitheredDepth8FormOn:aDevice
   284                    asFloydSteinbergDitheredDepth8FormOn:aDevice
   287 		   colors:cube
   285                    colors:cube
   288 		   nRed:nR
   286                    nRed:nR
   289 		   nGreen:nG
   287                    nGreen:nG
   290 		   nBlue:nB.
   288                    nBlue:nB.
   291 	] ifFalse:[
   289         ] ifFalse:[
   292 	    f := self
   290             f := self
   293 		   asNearestPaintDepth8FormOn:aDevice
   291                    asNearestPaintDepth8FormOn:aDevice
   294 		   colors:cube
   292                    colors:cube
   295 		   nRed:nR
   293                    nRed:nR
   296 		   nGreen:nG
   294                    nGreen:nG
   297 		   nBlue:nB.
   295                    nBlue:nB.
   298 	].
   296         ].
   299 	f notNil ifTrue:[^ f].
   297         f notNil ifTrue:[^ f].
   300     ].
   298     ].
   301 
   299 
   302     "find used colors"
   300     "find used colors"
   303     bytes := self bits.
   301     bytes := self bits.
   304     usedColors := bytes usedValues.    "gets us an array filled with used values"
   302     usedColors := bytes usedValues.    "gets us an array filled with used values"
   305 				       "(could use bytes asBag)"
   303                                        "(could use bytes asBag)"
   306     maxIndex := usedColors max + 1.
   304     maxIndex := usedColors max + 1.
   307 
   305 
   308     usedColors size > 20 ifTrue:[
   306     usedColors size > 20 ifTrue:[
   309 	('Depth8Image [info]: allocating ' , usedColors size printString , ' colors ...') infoPrintCR.
   307         ('Depth8Image [info]: allocating ' , usedColors size printString , ' colors ...') infoPrintCR.
   310     ].
   308     ].
   311 
   309 
   312     "sort by usage"
   310     "sort by usage"
   313     usageCounts := bytes usageCounts.
   311     usageCounts := bytes usageCounts.
   314     usageCounts := (usedColors collect:[:clr | usageCounts at:(clr + 1)]) asArray.
   312     usageCounts := (usedColors collect:[:clr | usageCounts at:(clr + 1)]) asArray.
   330     scale := 100.0 / div.       "to scale 0..255 into 0.0 .. 100.0"
   328     scale := 100.0 / div.       "to scale 0..255 into 0.0 .. 100.0"
   331     lastOK := 0.
   329     lastOK := 0.
   332     gcRound := 0.
   330     gcRound := 0.
   333 
   331 
   334     usedColors do:[:aColorIndex |
   332     usedColors do:[:aColorIndex |
   335 	|devColor color
   333         |devColor color
   336 	 r        "{Class: SmallInteger }"
   334          r        "{Class: SmallInteger }"
   337 	 g        "{Class: SmallInteger }"
   335          g        "{Class: SmallInteger }"
   338 	 b        "{Class: SmallInteger }"
   336          b        "{Class: SmallInteger }"
   339 	 mapIndex "{Class: SmallInteger }"|
   337          mapIndex "{Class: SmallInteger }"|
   340 
   338 
   341 	fit ifTrue:[
   339         fit ifTrue:[
   342 	    mapIndex := aColorIndex + 1.
   340             mapIndex := aColorIndex + 1.
   343 	    "/ color := colorMap at:mapIndex.
   341             "/ color := colorMap at:mapIndex.
   344 
   342 
   345 	    color := self colorFromValue:aColorIndex.
   343             color := self colorFromValue:aColorIndex.
   346 	    (color isOnDevice:aDevice) ifTrue:[
   344             (color isOnDevice:aDevice) ifTrue:[
   347 		"wow - an immediate hit"
   345                 "wow - an immediate hit"
   348 		devColor := color
   346                 devColor := color
   349 	    ] ifFalse:[
   347             ] ifFalse:[
   350 		devColor := color exactOn:aDevice.
   348                 devColor := color exactOn:aDevice.
   351 		devColor isNil ifTrue:[
   349                 devColor isNil ifTrue:[
   352 		    "
   350                     "
   353 		     could not allocate color - on the first round, do a GC to flush
   351                      could not allocate color - on the first round, do a GC to flush
   354 		     unused colors - this may help if some colors where locked by
   352                      unused colors - this may help if some colors where locked by
   355 		     already free images.
   353                      already free images.
   356 		    "
   354                     "
   357 		    gcRound == 0 ifTrue:[
   355                     gcRound == 0 ifTrue:[
   358 			ObjectMemory scavenge; finalize.
   356                         ObjectMemory scavenge; finalize.
   359 			devColor := color exactOn:aDevice.
   357                         devColor := color exactOn:aDevice.
   360 			gcRound := 1
   358                         gcRound := 1
   361 		    ].
   359                     ].
   362 		    devColor isNil ifTrue:[
   360                     devColor isNil ifTrue:[
   363 			gcRound == 1 ifTrue:[
   361                         gcRound == 1 ifTrue:[
   364 			    CollectGarbageWhenRunningOutOfColors ifTrue:[
   362                             CollectGarbageWhenRunningOutOfColors ifTrue:[
   365 				'Depth8Image [info]: force GC for possible color reclamation.' infoPrintCR.
   363                                 'Depth8Image [info]: force GC for possible color reclamation.' infoPrintCR.
   366 				ObjectMemory incrementalGC; finalize.
   364                                 ObjectMemory incrementalGC; finalize.
   367 				devColor := color exactOn:aDevice.
   365                                 devColor := color exactOn:aDevice.
   368 			    ].
   366                             ].
   369 			    gcRound := 2
   367                             gcRound := 2
   370 			]
   368                         ]
   371 		    ]
   369                     ]
   372 		].
   370                 ].
   373 	    ].
   371             ].
   374 	    (devColor notNil and:[devColor colorId notNil]) ifTrue:[
   372             (devColor notNil and:[devColor colorId notNil]) ifTrue:[
   375 		imgMap at:mapIndex put:devColor.
   373                 imgMap at:mapIndex put:devColor.
   376 		lastOK := lastOK + 1.
   374                 lastOK := lastOK + 1.
   377 	    ] ifFalse:[
   375             ] ifFalse:[
   378 		fit := false
   376                 fit := false
   379 	    ]
   377             ]
   380 	]
   378         ]
   381     ].
   379     ].
   382 
   380 
   383     fit ifFalse:[
   381     fit ifFalse:[
   384 	('Depth8Image [info]: got %1 exact colors (out of %2)' bindWith:lastOK with:usedColors size) infoPrintCR.
   382         ('Depth8Image [info]: got %1 exact colors (out of %2)' bindWith:lastOK with:usedColors size) infoPrintCR.
   385 
   383 
   386 	DitherAlgorithm == #floydSteinberg ifTrue:[
   384         DitherAlgorithm == #floydSteinberg ifTrue:[
   387 	    dColors := imgMap collect:[:clr | clr isNil ifTrue:[clr]
   385             dColors := imgMap collect:[:clr | clr isNil ifTrue:[clr]
   388 							ifFalse:[clr nearestOn:aDevice]].
   386                                                         ifFalse:[clr nearestOn:aDevice]].
   389 	    dColors := dColors select:[:clr | clr notNil] thenCollect:[:clr | clr exactOn:aDevice].
   387             dColors := dColors select:[:clr | clr notNil] thenCollect:[:clr | clr exactOn:aDevice].
   390 	    dColors := dColors asSet.
   388             dColors := dColors asSet.
   391 	    dColors addAll:(aDevice colorMap collect:[:c|c onDevice:aDevice] thenSelect:[:c | c colorId notNil]).
   389             dColors addAll:(aDevice colorMap collect:[:c|c onDevice:aDevice] thenSelect:[:c | c colorId notNil]).
   392 	    ditherColors := aDevice availableDitherColors.
   390             ditherColors := aDevice availableDitherColors.
   393 	    ditherColors notNil ifTrue:[
   391             ditherColors notNil ifTrue:[
   394 		dColors addAll:ditherColors.
   392                 dColors addAll:ditherColors.
   395 	    ].
   393             ].
   396 	    dColors := dColors asArray.
   394             dColors := dColors asArray.
   397 	    dColors size > 256 ifTrue:[
   395             dColors size > 256 ifTrue:[
   398 		dColors := dColors copyTo:256
   396                 dColors := dColors copyTo:256
   399 	    ].
   397             ].
   400 	    ^ self asFloydSteinbergDitheredPseudoFormUsing:dColors on:aDevice
   398             ^ self asFloydSteinbergDitheredPseudoFormUsing:dColors on:aDevice
   401 	].
   399         ].
   402 
   400 
   403 	"
   401         "
   404 	 again, this time allow wrong colors (loop while increasing allowed error)
   402          again, this time allow wrong colors (loop while increasing allowed error)
   405 	"
   403         "
   406 	error := 1.
   404         error := 1.
   407 	[fit] whileFalse:[
   405         [fit] whileFalse:[
   408 	    fit := true.
   406             fit := true.
   409 	    usedColors from:(lastOK+1) to:(usedColors size) do:[:aColorIndex |
   407             usedColors from:(lastOK+1) to:(usedColors size) do:[:aColorIndex |
   410 		|devColor color
   408                 |devColor color
   411 		 r        "{Class: SmallInteger }"
   409                  r        "{Class: SmallInteger }"
   412 		 g        "{Class: SmallInteger }"
   410                  g        "{Class: SmallInteger }"
   413 		 b        "{Class: SmallInteger }"
   411                  b        "{Class: SmallInteger }"
   414 		 mapIndex "{Class: SmallInteger }"
   412                  mapIndex "{Class: SmallInteger }"
   415 		 rMask    "{Class: SmallInteger }"
   413                  rMask    "{Class: SmallInteger }"
   416 		 gMask    "{Class: SmallInteger }"
   414                  gMask    "{Class: SmallInteger }"
   417 		 bMask    "{Class: SmallInteger }"|
   415                  bMask    "{Class: SmallInteger }"|
   418 
   416 
   419 		fit ifTrue:[
   417                 fit ifTrue:[
   420 		    gMask := bMask := rMask := m.
   418                     gMask := bMask := rMask := m.
   421 
   419 
   422 		    mapIndex := aColorIndex + 1.
   420                     mapIndex := aColorIndex + 1.
   423 		    "/ color := colorMap at:mapIndex.
   421                     "/ color := colorMap at:mapIndex.
   424 		    color := self colorFromValue:aColorIndex.
   422                     color := self colorFromValue:aColorIndex.
   425 		    r := (color red * 255 / 100.0) rounded.
   423                     r := (color red * 255 / 100.0) rounded.
   426 		    g := (color green * 255 / 100.0) rounded.
   424                     g := (color green * 255 / 100.0) rounded.
   427 		    b := (color blue * 255 / 100.0) rounded.
   425                     b := (color blue * 255 / 100.0) rounded.
   428 
   426 
   429 		    color := Color red:((r bitShift:shift) bitAnd:rMask) * scale
   427                     color := Color red:((r bitShift:shift) bitAnd:rMask) * scale
   430 				 green:((g bitShift:shift) bitAnd:gMask) * scale
   428                                  green:((g bitShift:shift) bitAnd:gMask) * scale
   431 				  blue:((b bitShift:shift) bitAnd:bMask) * scale.
   429                                   blue:((b bitShift:shift) bitAnd:bMask) * scale.
   432 
   430 
   433 		    (color isOnDevice:aDevice) ifTrue:[
   431                     (color isOnDevice:aDevice) ifTrue:[
   434 			"wow - an immediate hit"
   432                         "wow - an immediate hit"
   435 			devColor := color.
   433                         devColor := color.
   436 		    ] ifFalse:[
   434                     ] ifFalse:[
   437 			devColor := color nearestOn:aDevice.
   435                         devColor := color nearestOn:aDevice.
   438 			(devColor notNil and:[(devColor deltaFrom:color) > error]) ifTrue:[
   436                         (devColor notNil and:[(devColor deltaFrom:color) > error]) ifTrue:[
   439 			    devColor := nil
   437                             devColor := nil
   440 			].
   438                         ].
   441 			devColor isNil ifTrue:[
   439                         devColor isNil ifTrue:[
   442 			    "
   440                             "
   443 			     no free color - on the first round, do a GC to flush unused
   441                              no free color - on the first round, do a GC to flush unused
   444 			     colors - this may help if some colors where locked by already
   442                              colors - this may help if some colors where locked by already
   445 			     free images.
   443                              free images.
   446 			    "
   444                             "
   447 			    gcRound == 0 ifTrue:[
   445                             gcRound == 0 ifTrue:[
   448 				ObjectMemory scavenge; finalize.
   446                                 ObjectMemory scavenge; finalize.
   449 				devColor := color nearestOn:aDevice.
   447                                 devColor := color nearestOn:aDevice.
   450 				(devColor notNil and:[(devColor deltaFrom:color) > error]) ifTrue:[
   448                                 (devColor notNil and:[(devColor deltaFrom:color) > error]) ifTrue:[
   451 				    devColor := nil
   449                                     devColor := nil
   452 				].
   450                                 ].
   453 				gcRound := 1
   451                                 gcRound := 1
   454 			    ].
   452                             ].
   455 			    devColor isNil ifTrue:[
   453                             devColor isNil ifTrue:[
   456 				gcRound == 1 ifTrue:[
   454                                 gcRound == 1 ifTrue:[
   457 				    CollectGarbageWhenRunningOutOfColors ifTrue:[
   455                                     CollectGarbageWhenRunningOutOfColors ifTrue:[
   458 					'Depth8Image [info]: force GC for possible color reclamation.' infoPrintCR.
   456                                         'Depth8Image [info]: force GC for possible color reclamation.' infoPrintCR.
   459 					ObjectMemory incrementalGC; finalize.
   457                                         ObjectMemory incrementalGC; finalize.
   460 					devColor := color nearestOn:aDevice.
   458                                         devColor := color nearestOn:aDevice.
   461 					(devColor notNil and:[(devColor deltaFrom:color) > error]) ifTrue:[
   459                                         (devColor notNil and:[(devColor deltaFrom:color) > error]) ifTrue:[
   462 					    devColor := nil
   460                                             devColor := nil
   463 					].
   461                                         ].
   464 				    ].
   462                                     ].
   465 				    gcRound := 2
   463                                     gcRound := 2
   466 				]
   464                                 ]
   467 			    ]
   465                             ]
   468 			].
   466                         ].
   469 		    ].
   467                     ].
   470 		    (devColor notNil and:[devColor colorId notNil]) ifTrue:[
   468                     (devColor notNil and:[devColor colorId notNil]) ifTrue:[
   471 			imgMap at:mapIndex put:devColor.
   469                         imgMap at:mapIndex put:devColor.
   472 			lastOK := lastOK + 1.
   470                         lastOK := lastOK + 1.
   473 		    ] ifFalse:[
   471                     ] ifFalse:[
   474 			fit := false
   472                         fit := false
   475 		    ]
   473                     ]
   476 		].
   474                 ].
   477 	    ].
   475             ].
   478 
   476 
   479 	    fit ifTrue:[
   477             fit ifTrue:[
   480 		('Depth8Image [info]: remaining colors with error <= %1' bindWith:error) infoPrintCR.
   478                 ('Depth8Image [info]: remaining colors with error <= %1' bindWith:error) infoPrintCR.
   481 	    ].
   479             ].
   482 
   480 
   483 	    error := error * 2.
   481             error := error * 2.
   484 	    error > 100 ifTrue:[
   482             error > 100 ifTrue:[
   485 		"
   483                 "
   486 		 break out, if the error becomes too big.
   484                  break out, if the error becomes too big.
   487 		"
   485                 "
   488 		'Depth8Image [info]: hard color allocation problem - revert to b&w for remaining colors' infoPrintCR.
   486                 'Depth8Image [info]: hard color allocation problem - revert to b&w for remaining colors' infoPrintCR.
   489 		"
   487                 "
   490 		 map to b&w as a last fallback.
   488                  map to b&w as a last fallback.
   491 		 (should really do a dither here)
   489                  (should really do a dither here)
   492 		"
   490                 "
   493 		usedColors from:(lastOK+1) to:(usedColors size) do:[:aColorIndex |
   491                 usedColors from:(lastOK+1) to:(usedColors size) do:[:aColorIndex |
   494 		    |color
   492                     |color
   495 		     mapIndex "{ Class: SmallInteger }"|
   493                      mapIndex "{ Class: SmallInteger }"|
   496 
   494 
   497 		    mapIndex := aColorIndex + 1.
   495                     mapIndex := aColorIndex + 1.
   498 		    "/ color := colorMap at:mapIndex.
   496                     "/ color := colorMap at:mapIndex.
   499 		    color := self colorFromValue:aColorIndex.
   497                     color := self colorFromValue:aColorIndex.
   500 		    color brightness > 0.4 ifTrue:[
   498                     color brightness > 0.4 ifTrue:[
   501 			color := Color white.
   499                         color := Color white.
   502 		    ] ifFalse:[
   500                     ] ifFalse:[
   503 			color := Color black.
   501                         color := Color black.
   504 		    ].
   502                     ].
   505 		    imgMap at:mapIndex put:(color onDevice:aDevice).
   503                     imgMap at:mapIndex put:(color onDevice:aDevice).
   506 		].
   504                 ].
   507 		fit := true.
   505                 fit := true.
   508 	    ]
   506             ]
   509 	].
   507         ].
   510 
   508 
   511 	error > 10 ifTrue:[
   509         error > 10 ifTrue:[
   512 	    'Depth8Image [info]: not enough colors for a reasonable image' infoPrintCR
   510             'Depth8Image [info]: not enough colors for a reasonable image' infoPrintCR
   513 	] ifFalse:[
   511         ] ifFalse:[
   514 	    'Depth8Image [info]: not enough colors for exact picture' infoPrintCR.
   512             'Depth8Image [info]: not enough colors for exact picture' infoPrintCR.
   515 	]
   513         ]
   516     ].
   514     ].
   517 
   515 
   518     "
   516     "
   519      create translation map (from image colors to allocated colorIds)
   517      create translation map (from image colors to allocated colorIds)
   520     "
   518     "
   521     mapSize := imgMap size.
   519     mapSize := imgMap size.
   522     map := ByteArray new:256.
   520     map := ByteArray new:256.
   523     1 to:mapSize do:[:i |
   521     1 to:mapSize do:[:i |
   524 	(clr := imgMap at:i) notNil ifTrue:[
   522         (clr := imgMap at:i) notNil ifTrue:[
   525 	    map at:i put:clr colorId
   523             map at:i put:clr colorId
   526 	]
   524         ]
   527     ].
   525     ].
   528 
   526 
   529     "
   527     "
   530      does the device support 8-bit images ?
   528      does the device support 8-bit images ?
   531     "
   529     "
   532     deviceDepth := aDevice depth.
   530     deviceDepth := aDevice depth.
   533     has8BitImage := (deviceDepth == 8)
   531     has8BitImage := (deviceDepth == 8)
   534 		    or:[ (aDevice supportedImageFormatForDepth:8) notNil ].
   532                     or:[ (aDevice supportedImageFormatForDepth:8) notNil ].
   535 
   533 
   536     "
   534     "
   537      finally, create a form on the device and copy (& translate)
   535      finally, create a form on the device and copy (& translate)
   538      the pixel values
   536      the pixel values
   539     "
   537     "
   540     has8BitImage ifTrue:[
   538     has8BitImage ifTrue:[
   541 	pseudoBits := ByteArray uninitializedNew:(width * height).
   539         pseudoBits := ByteArray uninitializedNew:(width * height).
   542 
   540 
   543 	bytes
   541         bytes
   544 	    expandPixels:8         "xlate only"
   542             expandPixels:8         "xlate only"
   545 	    width:width height:height
   543             width:width height:height
   546 	    into:pseudoBits
   544             into:pseudoBits
   547 	    mapping:map.
   545             mapping:map.
   548 
   546 
   549 	map := nil.
   547         map := nil.
   550 
   548 
   551 	f := Form width:width height:height depth:deviceDepth onDevice:aDevice.
   549         f := Form width:width height:height depth:deviceDepth onDevice:aDevice.
   552 	f isNil ifTrue:[^ nil].
   550         f isNil ifTrue:[^ nil].
   553 	f colorMap:imgMap.
   551         f colorMap:imgMap.
   554 	f initGC.
   552         f initGC.
   555 	aDevice
   553         aDevice
   556 	    drawBits:pseudoBits
   554             drawBits:pseudoBits
   557 	    bitsPerPixel:8
   555             bitsPerPixel:8
   558 	    depth:deviceDepth
   556             depth:deviceDepth
   559 	    padding:8
   557             padding:8
   560 	    width:width height:height
   558             width:width height:height
   561 	    x:0 y:0
   559             x:0 y:0
   562 	    into:(f id) x:0 y:0
   560             into:(f id) x:0 y:0
   563 	    width:width height:height
   561             width:width height:height
   564 	    with:(f gcId).
   562             with:(f gcId).
   565 	^ f
   563         ^ f
   566     ].
   564     ].
   567 
   565 
   568     "
   566     "
   569      slow fall back: convert into appropriate depth image,
   567      slow fall back: convert into appropriate depth image,
   570      by looping over each pixel individually
   568      by looping over each pixel individually
   573     newImage width:width.
   571     newImage width:width.
   574     newImage height:height.
   572     newImage height:height.
   575     newImage bits:(ByteArray uninitializedNew:(height * newImage bytesPerRow)).
   573     newImage bits:(ByteArray uninitializedNew:(height * newImage bytesPerRow)).
   576 
   574 
   577     0 to:height-1 do:[:row |
   575     0 to:height-1 do:[:row |
   578 	pixelRow := self rowAt:row.
   576         pixelRow := self rowAt:row.
   579 	pixelRow
   577         pixelRow
   580 	    expandPixels:8         "xlate only"
   578             expandPixels:8         "xlate only"
   581 	    width:width
   579             width:width
   582 	    height:1
   580             height:1
   583 	    into:pixelRow
   581             into:pixelRow
   584 	    mapping:map.
   582             mapping:map.
   585 	newImage rowAt:row putAll:pixelRow
   583         newImage rowAt:row putAll:pixelRow
   586     ].
   584     ].
   587 
   585 
   588     f := Form width:width height:height depth:deviceDepth onDevice:aDevice.
   586     f := Form width:width height:height depth:deviceDepth onDevice:aDevice.
   589     f isNil ifTrue:[^ nil].
   587     f isNil ifTrue:[^ nil].
   590     f colorMap:imgMap.
   588     f colorMap:imgMap.
   591     f initGC.
   589     f initGC.
   592 
   590 
   593     aDevice
   591     aDevice
   594 	drawBits:(newImage bits)
   592         drawBits:(newImage bits)
   595 	depth:deviceDepth
   593         depth:deviceDepth
   596 	padding:8
   594         padding:8
   597 	width:width height:height
   595         width:width height:height
   598 	x:0 y:0
   596         x:0 y:0
   599 	into:(f id) x:0 y:0
   597         into:(f id) x:0 y:0
   600 	width:width height:height
   598         width:width height:height
   601 	with:(f gcId).
   599         with:(f gcId).
   602 
   600 
   603     ^ f
   601     ^ f
   604 
   602 
   605     "Modified: 15.10.1997 / 01:48:20 / cg"
   603     "Modified: 15.10.1997 / 01:48:20 / cg"
   606     "Created: 19.10.1997 / 04:57:05 / cg"
   604     "Created: 19.10.1997 / 04:57:05 / cg"
  1024     "Modified: 10.6.1996 / 18:54:36 / cg"
  1022     "Modified: 10.6.1996 / 18:54:36 / cg"
  1025 !
  1023 !
  1026 
  1024 
  1027 greyImageAsPseudoFormOn:aDevice
  1025 greyImageAsPseudoFormOn:aDevice
  1028     "return a pseudoForm from the gray picture. The main work is
  1026     "return a pseudoForm from the gray picture. The main work is
  1029      in color reduction, when not all colors can be aquired."
  1027      in color reduction, when not all colors can be acquired."
  1030 
  1028 
  1031     ^ self anyImageAsPseudoFormOn:aDevice
  1029     ^ self anyImageAsPseudoFormOn:aDevice
  1032 
  1030 
  1033     "Modified: 19.10.1997 / 04:57:39 / cg"
  1031     "Modified: 19.10.1997 / 04:57:39 / cg"
  1034     "Created: 19.10.1997 / 04:58:41 / cg"
  1032     "Created: 19.10.1997 / 04:58:41 / cg"
  1047     "Created: / 29.7.1998 / 00:19:46 / cg"
  1045     "Created: / 29.7.1998 / 00:19:46 / cg"
  1048 !
  1046 !
  1049 
  1047 
  1050 paletteImageAsPseudoFormOn:aDevice
  1048 paletteImageAsPseudoFormOn:aDevice
  1051     "return a pseudoForm from the palette picture. The main work is
  1049     "return a pseudoForm from the palette picture. The main work is
  1052      in color reduction, when not all colors can be aquired."
  1050      in color reduction, when not all colors can be acquired."
  1053 
  1051 
  1054     ^ self anyImageAsPseudoFormOn:aDevice
  1052     ^ self anyImageAsPseudoFormOn:aDevice
  1055 
  1053 
  1056     "Modified: 19.10.1997 / 04:57:39 / cg"
  1054     "Modified: 19.10.1997 / 04:57:39 / cg"
  1057 !
  1055 !