changeset 4717 | c25149336a26 |
parent 4620 | a9d593b2a056 |
child 4725 | c8896df7bd3f |
4716:d4fb48e2c72d | 4717:c25149336a26 |
---|---|
45 |
45 |
46 documentation |
46 documentation |
47 " |
47 " |
48 this class provides (some time in the future) representation |
48 this class provides (some time in the future) representation |
49 for all kinds of images (monochrome, greyscale and color) |
49 for all kinds of images (monochrome, greyscale and color) |
50 and will finally replace Form. |
50 and will finally replace Form. |
51 For now (only ;-) depths of 1, 2, 4, 8, 16 and 24 are supported. |
51 For now (only ;-) depths of 1, 2, 4, 8, 16 and 24 are supported. |
52 |
52 |
53 An Image keeps all of its information in a device independent way, |
53 An Image keeps all of its information in a device independent way, |
54 but may be associated to a device. |
54 but may be associated to a device. |
55 The data held keeps all information which was originally present, |
55 The data held keeps all information which was originally present, |
56 even if the display-device has lower resolution. |
56 even if the display-device has lower resolution. |
57 Therefore, it is possible to process and manipulate images without loosing |
57 Therefore, it is possible to process and manipulate images without loosing |
58 color information. |
58 color information. |
59 |
59 |
60 Images may be created manually (by providing a pixel array), |
60 Images may be created manually (by providing a pixel array), |
61 by screen capture or by reading a file (using an ImageReader). |
61 by screen capture or by reading a file (using an ImageReader). |
62 This gives a device independent image. |
62 This gives a device independent image. |
63 For display, a device representation is required, which can be |
63 For display, a device representation is required, which can be |
64 aquired by sending the |
64 aquired by sending the |
65 'onDevice:aDevice' |
65 'onDevice:aDevice' |
66 message to the image. This will create a (possibly dithered) device-form, |
66 message to the image. This will create a (possibly dithered) device-form, |
67 representing the image using the currently available colors. |
67 representing the image using the currently available colors. |
68 |
68 |
69 In rare cases, an explicit monochrome representation of the image is needed |
69 In rare cases, an explicit monochrome representation of the image is needed |
70 (X servers take monochrome icons only), this can be created by sending |
70 (X servers take monochrome icons only), this can be created by sending |
71 it the message |
71 it the message |
72 'monochromeOn:aDevice'. |
72 'monochromeOn:aDevice'. |
73 |
73 |
74 Also, it is planned to generate another hi-color resolution version, |
74 Also, it is planned to generate another hi-color resolution version, |
75 which uses its own colormap and allows the use of all 256 colors on an 8bit display |
75 which uses its own colormap and allows the use of all 256 colors on an 8bit display |
76 (this is not currently implemented). |
76 (this is not currently implemented). |
77 |
77 |
78 An images pixel interpretation is controlled by the photometric instance variable |
78 An images pixel interpretation is controlled by the photometric instance variable |
79 and (if that is #palette) a colorMap. |
79 and (if that is #palette) a colorMap. |
80 This is in contrast to the ST-80 way, where all of this info is in the colorMap |
80 This is in contrast to the ST-80 way, where all of this info is in the colorMap |
81 (and using specialized colorMaps for b&w / greyScale images). |
81 (and using specialized colorMaps for b&w / greyScale images). |
82 This may change in future versions for more application compatibility. |
82 This may change in future versions for more application compatibility. |
83 |
83 |
84 To convert pictures from/to external file-formats, image readers are used |
84 To convert pictures from/to external file-formats, image readers are used |
85 which have the file-format knowledge built in. |
85 which have the file-format knowledge built in. |
86 There are readers for most common formats available |
86 There are readers for most common formats available |
87 (see ImageReader and especially subclasses such as TIFFReader, GIFReader etc.). |
87 (see ImageReader and especially subclasses such as TIFFReader, GIFReader etc.). |
88 |
88 |
89 File formats are handled by subclasses of ImageReader, which understand |
89 File formats are handled by subclasses of ImageReader, which understand |
90 a specific format. You can add more readers, by adding an association |
90 a specific format. You can add more readers, by adding an association |
91 such as ('.jpg' -> JPEGReader) to the class variable 'FileFormats' |
91 such as ('.jpg' -> JPEGReader) to the class variable 'FileFormats' |
92 (see the classes #initialize method, which sets up some default, and the |
92 (see the classes #initialize method, which sets up some default, and the |
93 patches/display.rc files, which add more). |
93 patches/display.rc files, which add more). |
94 |
94 |
95 Some algorithms used here (especially dithering & color allocation) are |
95 Some algorithms used here (especially dithering & color allocation) are |
96 experimental and far from being perfect (some are very slow). |
96 experimental and far from being perfect (some are very slow). |
97 For now, the most common cases have been optimized and perform reasonably |
97 For now, the most common cases have been optimized and perform reasonably |
98 fast - however, with uncommon depth/visualType combinations, you may |
98 fast - however, with uncommon depth/visualType combinations, you may |
99 run into slower fallback methods ... |
99 run into slower fallback methods ... |
100 |
100 |
101 Much more work is needed if you plan to do heavy image processing and will |
101 Much more work is needed if you plan to do heavy image processing and will |
156 image was loaded - nil otherwise. |
156 image was loaded - nil otherwise. |
157 Useful for image save functions |
157 Useful for image save functions |
158 and for the UIPainter utility. |
158 and for the UIPainter utility. |
159 |
159 |
160 imageSequence the imageSequence, of which the |
160 imageSequence the imageSequence, of which the |
161 instance is a frame or nil, |
161 instance is a frame or nil, |
162 if its not part of a sequence. |
162 if its not part of a sequence. |
163 |
163 |
164 bitsPerPixel not used in ST/X |
164 bitsPerPixel not used in ST/X |
165 depth - these have been added in instVar-slots |
165 depth - these have been added in instVar-slots |
166 maxPixelValue - according to the ST-80's image class. |
166 maxPixelValue - according to the ST-80's image class. |
188 Default is true. |
188 Default is true. |
189 |
189 |
190 ImageNotFoundQuerySignal |
190 ImageNotFoundQuerySignal |
191 <QuerySignal> raised, if an image could not be loaded |
191 <QuerySignal> raised, if an image could not be loaded |
192 from a file. The parameter is the images |
192 from a file. The parameter is the images |
193 fileName. |
193 fileName. |
194 A handler may return a replacement |
194 A handler may return a replacement |
195 image or proceed with nil. |
195 image or proceed with nil. |
196 If unhandled, a nil is returned from the |
196 If unhandled, a nil is returned from the |
197 image creation. |
197 image creation. |
198 |
198 |
199 BadImageFormatQuerySignal |
199 BadImageFormatQuerySignal |
200 <QuerySignal> raised, if an image could not be loaded |
200 <QuerySignal> raised, if an image could not be loaded |
201 from a file due to a file error or |
201 from a file due to a file error or |
202 unsupported format. |
202 unsupported format. |
203 A handler may return a replacement |
203 A handler may return a replacement |
204 image or proceed with nil. |
204 image or proceed with nil. |
205 If unhandled, a nil is returned from the |
205 If unhandled, a nil is returned from the |
206 image creation. |
206 image creation. |
207 |
207 |
314 |
314 |
315 a depth4 greyScale image: |
315 a depth4 greyScale image: |
316 (default photometric is #blackIs0) |
316 (default photometric is #blackIs0) |
317 [exBegin] |
317 [exBegin] |
318 (Depth4Image |
318 (Depth4Image |
319 width:8 |
319 width:8 |
320 height:4 |
320 height:4 |
321 fromArray:#[ |
321 fromArray:#[ |
322 16r00 16r11 16r22 16r33 |
322 16r00 16r11 16r22 16r33 |
323 16r44 16r55 16r66 16r77 |
323 16r44 16r55 16r66 16r77 |
324 16r88 16r99 16raa 16rbb |
324 16r88 16r99 16raa 16rbb |
325 16rcc 16rdd 16ree 16rff |
325 16rcc 16rdd 16ree 16rff |
326 ]) inspect |
326 ]) inspect |
327 [exEnd] |
327 [exEnd] |
328 the same, magnified: |
328 the same, magnified: |
329 [exBegin] |
329 [exBegin] |
330 ((Depth4Image |
330 ((Depth4Image |
331 width:4 |
331 width:4 |
332 height:4 |
332 height:4 |
333 fromArray:#[ |
333 fromArray:#[ |
334 16r01 16r23 |
334 16r01 16r23 |
335 16r45 16r67 |
335 16r45 16r67 |
336 16r89 16rab |
336 16r89 16rab |
337 16rcd 16ref |
337 16rcd 16ref |
338 ]) |
338 ]) |
339 magnifiedBy:30) |
339 magnifiedBy:30) |
340 inspect |
340 inspect |
341 [exEnd] |
341 [exEnd] |
342 the following has the same effect: |
342 the following has the same effect: |
343 [exBegin] |
343 [exBegin] |
344 ((Image |
344 ((Image |
345 width:4 |
345 width:4 |
346 height:4 |
346 height:4 |
347 depth:4 |
347 depth:4 |
348 fromArray:#[ |
348 fromArray:#[ |
349 16r01 16r23 |
349 16r01 16r23 |
350 16r45 16r67 |
350 16r45 16r67 |
351 16r89 16rab |
351 16r89 16rab |
352 16rcd 16ref |
352 16rcd 16ref |
353 ]) |
353 ]) |
354 magnifiedBy:30) |
354 magnifiedBy:30) |
355 inspect |
355 inspect |
356 [exEnd] |
356 [exEnd] |
357 with reverse grey-interpretation: |
357 with reverse grey-interpretation: |
358 [exBegin] |
358 [exBegin] |
359 ((Depth4Image |
359 ((Depth4Image |
360 width:4 |
360 width:4 |
361 height:4 |
361 height:4 |
362 fromArray:#[ |
362 fromArray:#[ |
363 16r01 16r23 |
363 16r01 16r23 |
364 16r45 16r67 |
364 16r45 16r67 |
365 16r89 16rab |
365 16r89 16rab |
366 16rcd 16ref |
366 16rcd 16ref |
367 ]) |
367 ]) |
368 photometric:#whiteIs0; |
368 photometric:#whiteIs0; |
369 magnifiedBy:30) |
369 magnifiedBy:30) |
370 inspect |
370 inspect |
371 [exEnd] |
371 [exEnd] |
372 |
372 |
373 with 1-bit-per-pixel rgb interpretation: |
373 with 1-bit-per-pixel rgb interpretation: |
374 [exBegin] |
374 [exBegin] |
375 ((Depth4Image |
375 ((Depth4Image |
376 width:4 |
376 width:4 |
377 height:4 |
377 height:4 |
378 fromArray:#[ |
378 fromArray:#[ |
379 16r01 16r23 |
379 16r01 16r23 |
380 16r45 16r67 |
380 16r45 16r67 |
381 16r89 16rab |
381 16r89 16rab |
382 16rcd 16ref |
382 16rcd 16ref |
383 ]) |
383 ]) |
384 photometric:#rgb; |
384 photometric:#rgb; |
385 samplesPerPixel:3; |
385 samplesPerPixel:3; |
386 bitsPerSample:#(1 1 1); |
386 bitsPerSample:#(1 1 1); |
387 magnifiedBy:30) |
387 magnifiedBy:30) |
389 [exEnd] |
389 [exEnd] |
390 |
390 |
391 with 1/2/1 rgb interpretation: |
391 with 1/2/1 rgb interpretation: |
392 [exBegin] |
392 [exBegin] |
393 ((Depth4Image |
393 ((Depth4Image |
394 width:4 |
394 width:4 |
395 height:4 |
395 height:4 |
396 fromArray:#[ |
396 fromArray:#[ |
397 16r01 16r23 |
397 16r01 16r23 |
398 16r45 16r67 |
398 16r45 16r67 |
399 16r89 16rab |
399 16r89 16rab |
400 16rcd 16ref |
400 16rcd 16ref |
401 ]) |
401 ]) |
402 photometric:#rgb; |
402 photometric:#rgb; |
403 samplesPerPixel:3; |
403 samplesPerPixel:3; |
404 bitsPerSample:#(1 2 1); |
404 bitsPerSample:#(1 2 1); |
405 magnifiedBy:30) |
405 magnifiedBy:30) |
447 |
447 |
448 |
448 |
449 a 2plane greyscale image: |
449 a 2plane greyscale image: |
450 [exBegin] |
450 [exBegin] |
451 ((Depth2Image |
451 ((Depth2Image |
452 width:4 |
452 width:4 |
453 height:4 |
453 height:4 |
454 fromArray:#[ |
454 fromArray:#[ |
455 4r0123 |
455 4r0123 |
456 4r1230 |
456 4r1230 |
457 4r2301 |
457 4r2301 |
458 4r3012 |
458 4r3012 |
459 ]) |
459 ]) |
460 magnifiedBy:30) |
460 magnifiedBy:30) |
461 inspect |
461 inspect |
462 [exEnd] |
462 [exEnd] |
463 |
463 |
464 with colors: |
464 with colors: |
465 [exBegin] |
465 [exBegin] |
466 ((Depth2Image |
466 ((Depth2Image |
467 width:4 |
467 width:4 |
468 height:4 |
468 height:4 |
469 fromArray:#[ |
469 fromArray:#[ |
470 4r0123 |
470 4r0123 |
471 4r1230 |
471 4r1230 |
472 4r2301 |
472 4r2301 |
473 4r3012 |
473 4r3012 |
474 ]) |
474 ]) |
475 colorMap:(Array with:(Color black) |
475 colorMap:(Array with:(Color black) |
476 with:(Color red) |
476 with:(Color red) |
477 with:(Color green) |
477 with:(Color green) |
478 with:(Color blue)); |
478 with:(Color blue)); |
481 [exEnd] |
481 [exEnd] |
482 |
482 |
483 depth8 image with 3/3/2 rgb interpretation: |
483 depth8 image with 3/3/2 rgb interpretation: |
484 [exBegin] |
484 [exBegin] |
485 ((Depth8Image |
485 ((Depth8Image |
486 width:16 |
486 width:16 |
487 height:16 |
487 height:16 |
488 fromArray:(ByteArray withAll:(0 to:16rFF))) |
488 fromArray:(ByteArray withAll:(0 to:16rFF))) |
489 photometric:#rgb; |
489 photometric:#rgb; |
490 samplesPerPixel:3; |
490 samplesPerPixel:3; |
491 bitsPerSample:#(3 3 2); |
491 bitsPerSample:#(3 3 2); |
494 [exEnd] |
494 [exEnd] |
495 |
495 |
496 depth8 image with 2/2/2 rgb interpretation: |
496 depth8 image with 2/2/2 rgb interpretation: |
497 [exBegin] |
497 [exBegin] |
498 ((Depth8Image |
498 ((Depth8Image |
499 width:8 |
499 width:8 |
500 height:8 |
500 height:8 |
501 fromArray:(ByteArray withAll:(0 to:16r3F))) |
501 fromArray:(ByteArray withAll:(0 to:16r3F))) |
502 photometric:#rgb; |
502 photometric:#rgb; |
503 samplesPerPixel:3; |
503 samplesPerPixel:3; |
504 bitsPerSample:#(2 2 2); |
504 bitsPerSample:#(2 2 2); |
507 [exEnd] |
507 [exEnd] |
508 |
508 |
509 trueColor image: |
509 trueColor image: |
510 [exBegin] |
510 [exBegin] |
511 ((Depth24Image |
511 ((Depth24Image |
512 width:4 |
512 width:4 |
513 height:4 |
513 height:4 |
514 fromArray:#[ |
514 fromArray:#[ |
515 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
515 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
516 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 |
516 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 |
517 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF |
517 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF |
518 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF |
518 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF |
519 ]) |
519 ]) |
520 photometric:#rgb; |
520 photometric:#rgb; |
521 samplesPerPixel:3; |
521 samplesPerPixel:3; |
522 bitsPerSample:#(8 8 8); |
522 bitsPerSample:#(8 8 8); |
533 (Image fromFile:'myImage.tiff') inspect |
533 (Image fromFile:'myImage.tiff') inspect |
534 [exEnd] |
534 [exEnd] |
535 |
535 |
536 magnifying (any factor): |
536 magnifying (any factor): |
537 [exBegin] |
537 [exBegin] |
538 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
538 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
539 magnifiedTo:(48@48)) |
539 magnifiedTo:(48@48)) |
540 inspect |
540 inspect |
541 [exEnd] |
541 [exEnd] |
542 [exBegin] |
542 [exBegin] |
543 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
543 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
544 magnifiedBy:0.7) |
544 magnifiedBy:0.7) |
545 inspect |
545 inspect |
546 [exEnd] |
546 [exEnd] |
547 |
547 |
548 rotating: |
548 rotating: |
549 [exBegin] |
549 [exBegin] |
550 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
550 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
551 rotated:90) |
551 rotated:90) |
552 inspect |
552 inspect |
553 [exEnd] |
553 [exEnd] |
554 [exBegin] |
554 [exBegin] |
555 (((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
555 (((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
556 magnifiedBy:0.3@0.7) rotated:270) |
556 magnifiedBy:0.3@0.7) rotated:270) |
557 inspect |
557 inspect |
558 [exEnd] |
558 [exEnd] |
559 [exBegin] |
559 [exBegin] |
560 (((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
560 (((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
561 ) rotated:30) |
561 ) rotated:30) |
562 inspect |
562 inspect |
563 [exEnd] |
563 [exEnd] |
564 negative: |
564 negative: |
565 [exBegin] |
565 [exBegin] |
566 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
566 ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
567 negative) |
567 negative) |
568 inspect |
568 inspect |
569 [exEnd] |
569 [exEnd] |
570 " |
570 " |
571 ! ! |
571 ! ! |
627 "setup tracker of known pictures" |
627 "setup tracker of known pictures" |
628 Lobby isNil ifTrue:[ |
628 Lobby isNil ifTrue:[ |
629 Lobby := Registry new. |
629 Lobby := Registry new. |
630 ObjectMemory addDependent:self. |
630 ObjectMemory addDependent:self. |
631 |
631 |
632 "/ define the algorithm to use for dithering - |
632 "/ define the algorithm to use for dithering - |
633 "/ supported values are: |
633 "/ supported values are: |
634 "/ #threshold |
634 "/ #threshold |
635 "/ #ordered |
635 "/ #ordered |
636 "/ #floydSteinberg |
636 "/ #floydSteinberg |
637 "/ #burkes |
637 "/ #burkes |
638 |
638 |
639 DitherAlgorithm := #floydSteinberg. |
639 DitherAlgorithm := #floydSteinberg. |
640 |
640 |
641 (Display notNil and:[Display hasGrayscales]) ifFalse:[ |
641 (Display notNil and:[Display hasGrayscales]) ifFalse:[ |
642 NumberOfDitherColors := 64 |
642 NumberOfDitherColors := 64 |
643 ] ifTrue:[ |
643 ] ifTrue:[ |
644 "as far as I remember, this is about the number of grey values, the eye can distinguish" |
644 "as far as I remember, this is about the number of grey values, the eye can distinguish" |
689 "initialize a default table to map from file extension to reader class. |
689 "initialize a default table to map from file extension to reader class. |
690 The mapping here is a default needed for proper operation of ST/X; |
690 The mapping here is a default needed for proper operation of ST/X; |
691 see the 'smalltalk.rc'/'display.rc' startup files for a real (full) map." |
691 see the 'smalltalk.rc'/'display.rc' startup files for a real (full) map." |
692 |
692 |
693 MIMETypes notNil ifTrue:[ |
693 MIMETypes notNil ifTrue:[ |
694 MIMETypes imageReaderForSuffix:'xbm' put:XBMReader. |
694 MIMETypes imageReaderForSuffix:'xbm' put:XBMReader. |
695 MIMETypes imageReaderForSuffix:'tiff' put:TIFFReader. |
695 MIMETypes imageReaderForSuffix:'tiff' put:TIFFReader. |
696 MIMETypes imageReaderForSuffix:'gif' put:GIFReader. |
696 MIMETypes imageReaderForSuffix:'gif' put:GIFReader. |
697 ]. |
697 ]. |
698 |
698 |
699 " |
699 " |
700 Image initializeFileFormatTable |
700 Image initializeFileFormatTable |
701 " |
701 " |
707 "initialize a default table to map from mime type to reader class. |
707 "initialize a default table to map from mime type to reader class. |
708 The mapping here is a default needed for proper operation of ST/X; |
708 The mapping here is a default needed for proper operation of ST/X; |
709 see the 'smalltalk.rc'/'display.rc' startup files for a real (full) map." |
709 see the 'smalltalk.rc'/'display.rc' startup files for a real (full) map." |
710 |
710 |
711 MIMETypes notNil ifTrue:[ |
711 MIMETypes notNil ifTrue:[ |
712 MIMETypes mimeTypeForSuffix:'gif' put:'image/gif'. |
712 MIMETypes mimeTypeForSuffix:'gif' put:'image/gif'. |
713 MIMETypes mimeTypeForSuffix:'tiff' put:'image/tiff'. |
713 MIMETypes mimeTypeForSuffix:'tiff' put:'image/tiff'. |
714 MIMETypes mimeTypeForSuffix:'tif' put:'image/tiff'. |
714 MIMETypes mimeTypeForSuffix:'tif' put:'image/tiff'. |
715 MIMETypes mimeTypeForSuffix:'xbm' put:'image/x-xbitmap'. |
715 MIMETypes mimeTypeForSuffix:'xbm' put:'image/x-xbitmap'. |
716 MIMETypes mimeTypeForSuffix:'xpm' put:'image/x-xpixmap'. |
716 MIMETypes mimeTypeForSuffix:'xpm' put:'image/x-xpixmap'. |
717 ]. |
717 ]. |
718 |
718 |
719 " |
719 " |
720 Image initializeMIMETable |
720 Image initializeMIMETable |
721 " |
721 " |
735 ! ! |
735 ! ! |
736 |
736 |
737 !Image class methodsFor:'instance creation'! |
737 !Image class methodsFor:'instance creation'! |
738 |
738 |
739 extent:ext |
739 extent:ext |
740 "create a new image, given extent. |
740 "create a new image, given extent. |
741 Assume a depth of 1, unless an explicit imageClass is the receiver." |
741 Assume a depth of 1, unless an explicit imageClass is the receiver." |
742 |
742 |
743 ^ self width:(ext x) height:(ext y) |
743 ^ self width:(ext x) height:(ext y) |
744 |
744 |
745 "Created: / 30.9.1998 / 22:31:26 / cg" |
745 "Created: / 30.9.1998 / 22:31:26 / cg" |
747 ! |
747 ! |
748 |
748 |
749 extent:ext depth:d |
749 extent:ext depth:d |
750 "ST-80 compatibility" |
750 "ST-80 compatibility" |
751 |
751 |
752 ^ self width:ext x height:ext y depth:d |
752 ^ self width:ext x height:ext y depth:d |
753 ! |
753 ! |
754 |
754 |
755 extent:ext depth:d bits:bits |
755 extent:ext depth:d bits:bits |
756 "ST-80 compatibility; assume 32-bit padding" |
756 "ST-80 compatibility; assume 32-bit padding" |
757 |
757 |
876 |
876 |
877 fromImage:anImage photometric:photometricOrNil |
877 fromImage:anImage photometric:photometricOrNil |
878 "create & return an Image given another image. This can be used to |
878 "create & return an Image given another image. This can be used to |
879 convert an image to another depth." |
879 convert an image to another depth." |
880 |
880 |
881 (self == Image |
881 (self == Image |
882 or:[anImage class == self |
882 or:[anImage class == self |
883 and:[photometricOrNil isNil or:[photometricOrNil == anImage photometric]]]) ifTrue:[^ anImage]. |
883 and:[photometricOrNil isNil or:[photometricOrNil == anImage photometric]]]) ifTrue:[^ anImage]. |
884 ^ self new fromImage:anImage photometric:photometricOrNil. |
884 ^ self new fromImage:anImage photometric:photometricOrNil. |
885 |
885 |
886 " |
886 " |
887 |i1 i8| |
887 |i1 i8| |
944 (Image fromSubForm:(5@5 corner:10@10) in:f) inspect |
944 (Image fromSubForm:(5@5 corner:10@10) in:f) inspect |
945 " |
945 " |
946 ! |
946 ! |
947 |
947 |
948 fromSubImage:anImage in:aRectangle |
948 fromSubImage:anImage in:aRectangle |
949 "create & return an Image from a rectangular area in another image. |
949 "create & return an Image from a rectangular area in another image. |
950 This can also be used to get a subimage in another depth." |
950 This can also be used to get a subimage in another depth." |
951 |
951 |
952 |cls newImage| |
952 |cls newImage| |
953 |
953 |
954 self == Image ifTrue:[ |
954 self == Image ifTrue:[ |
955 cls := (self implementorForDepth:anImage depth). |
955 cls := (self implementorForDepth:anImage depth). |
956 ] ifFalse:[ |
956 ] ifFalse:[ |
957 cls := self. |
957 cls := self. |
958 ]. |
958 ]. |
959 newImage := cls new. |
959 newImage := cls new. |
960 ^ newImage fromSubImage:anImage in:aRectangle. |
960 ^ newImage fromSubImage:anImage in:aRectangle. |
961 |
961 |
962 " |
962 " |
1033 width:w height:h depth:d fromArray:pixelData |
1033 width:w height:h depth:d fromArray:pixelData |
1034 "create a new image, given width, height, depth and data. |
1034 "create a new image, given width, height, depth and data. |
1035 Data must be a ByteArray containing correctly aligned bits for the specified |
1035 Data must be a ByteArray containing correctly aligned bits for the specified |
1036 depth (8-bit padded)." |
1036 depth (8-bit padded)." |
1037 |
1037 |
1038 ^ (self newForDepth:d) |
1038 ^ (self newForDepth:d) |
1039 width:w height:h depth:d fromArray:pixelData |
1039 width:w height:h depth:d fromArray:pixelData |
1040 |
1040 |
1041 " |
1041 " |
1042 Image width:8 |
1042 Image width:8 |
1043 height:8 |
1043 height:8 |
1044 depth:1 |
1044 depth:1 |
1045 fromArray:#[2r11001100 |
1045 fromArray:#[2r11001100 |
1046 2r00110011 |
1046 2r00110011 |
1047 2r11001100 |
1047 2r11001100 |
1051 2r11001100 |
1051 2r11001100 |
1052 2r00110011]. |
1052 2r00110011]. |
1053 " |
1053 " |
1054 |
1054 |
1055 " |
1055 " |
1056 Image width:8 |
1056 Image width:8 |
1057 height:8 |
1057 height:8 |
1058 depth:2 |
1058 depth:2 |
1059 fromArray:#[4r1100 4r1100 |
1059 fromArray:#[4r1100 4r1100 |
1060 4r0011 4r0011 |
1060 4r0011 4r0011 |
1061 4r1100 4r1100 |
1061 4r1100 4r1100 |
1062 4r0011 4r0011 |
1062 4r0011 4r0011 |
1063 4r1100 4r1100 |
1063 4r1100 4r1100 |
1065 4r1100 4r1100 |
1065 4r1100 4r1100 |
1066 4r0011 4r0011]. |
1066 4r0011 4r0011]. |
1067 " |
1067 " |
1068 |
1068 |
1069 " |
1069 " |
1070 Image width:8 |
1070 Image width:8 |
1071 height:8 |
1071 height:8 |
1072 depth:4 |
1072 depth:4 |
1073 fromArray:#[16r00 16r01 16rf0 16rf1 |
1073 fromArray:#[16r00 16r01 16rf0 16rf1 |
1074 16r02 16r03 16rf2 16rf3 |
1074 16r02 16r03 16rf2 16rf3 |
1075 16r04 16r05 16rf4 16rf5 |
1075 16r04 16r05 16rf4 16rf5 |
1076 16r06 16r07 16rf6 16rf7 |
1076 16r06 16r07 16rf6 16rf7 |
1077 16r08 16r09 16rf8 16rf9 |
1077 16r08 16r09 16rf8 16rf9 |
1086 width:w height:h depth:d fromArray:pixelData pad:padding |
1086 width:w height:h depth:d fromArray:pixelData pad:padding |
1087 "create a new image, given width, height, depth and data. |
1087 "create a new image, given width, height, depth and data. |
1088 Data must be a ByteArray containing correctly aligned bits for the specified |
1088 Data must be a ByteArray containing correctly aligned bits for the specified |
1089 depth." |
1089 depth." |
1090 |
1090 |
1091 |img newBits |
1091 |img newBits |
1092 srcRowBytes "{ Class: SmallInteger }" |
1092 srcRowBytes "{ Class: SmallInteger }" |
1093 dstRowBytes "{ Class: SmallInteger }" |
1093 dstRowBytes "{ Class: SmallInteger }" |
1094 nextDstIndex "{ Class: SmallInteger }" |
1094 nextDstIndex "{ Class: SmallInteger }" |
1095 srcIndex "{ Class: SmallInteger }" |
1095 srcIndex "{ Class: SmallInteger }" |
1096 dstIndex "{ Class: SmallInteger }" | |
1096 dstIndex "{ Class: SmallInteger }" | |
1108 srcIndex := 1. |
1108 srcIndex := 1. |
1109 dstIndex := 1. |
1109 dstIndex := 1. |
1110 |
1110 |
1111 1 to:h do:[:row | |
1111 1 to:h do:[:row | |
1112 nextDstIndex := dstIndex + dstRowBytes. |
1112 nextDstIndex := dstIndex + dstRowBytes. |
1113 newBits replaceFrom:dstIndex |
1113 newBits replaceFrom:dstIndex |
1114 to:(nextDstIndex - 1) |
1114 to:(nextDstIndex - 1) |
1115 with:pixelData |
1115 with:pixelData |
1116 startingAt:srcIndex. |
1116 startingAt:srcIndex. |
1117 srcIndex := srcIndex + srcRowBytes. |
1117 srcIndex := srcIndex + srcRowBytes. |
1118 dstIndex := nextDstIndex. |
1118 dstIndex := nextDstIndex. |
1151 pixels := anArray |
1151 pixels := anArray |
1152 ]. |
1152 ]. |
1153 ^ cls new width:w height:h depth:d fromArray:pixels |
1153 ^ cls new width:w height:h depth:d fromArray:pixels |
1154 |
1154 |
1155 " |
1155 " |
1156 Image width:8 |
1156 Image width:8 |
1157 height:8 |
1157 height:8 |
1158 fromArray:#[2r11001100 |
1158 fromArray:#[2r11001100 |
1159 2r00110011 |
1159 2r00110011 |
1160 2r11001100 |
1160 2r11001100 |
1161 2r00110011 |
1161 2r00110011 |
1162 2r11001100 |
1162 2r11001100 |
1264 "Created: 1.2.1997 / 14:40:29 / cg" |
1264 "Created: 1.2.1997 / 14:40:29 / cg" |
1265 ! ! |
1265 ! ! |
1266 |
1266 |
1267 !Image class methodsFor:'cleanup'! |
1267 !Image class methodsFor:'cleanup'! |
1268 |
1268 |
1269 releaseResourcesOnDevice:aDevice |
1269 releaseResourcesOnDevice:aDevice |
1270 "this is sent when a display connection is closed, |
1270 "this is sent when a display connection is closed, |
1271 to release all cached Images from that device" |
1271 to release all cached Images from that device" |
1272 |
1272 |
1273 Lobby |
1273 Lobby |
1274 unregisterAllForWhich:[:eachImage | |
1274 unregisterAllForWhich:[:eachImage | |
1275 |ok| |
1275 |ok| |
1276 |
1276 |
1277 ok := eachImage graphicsDevice == aDevice. |
1277 ok := eachImage graphicsDevice == aDevice. |
1278 ok ifTrue:[ |
1278 ok ifTrue:[ |
1279 eachImage releaseFromDevice |
1279 eachImage releaseFromDevice |
1280 ]. |
1280 ]. |
1281 ok |
1281 ok |
1282 ] |
1282 ] |
1283 |
1283 |
1284 "Created: 16.1.1997 / 19:30:44 / cg" |
1284 "Created: 16.1.1997 / 19:30:44 / cg" |
1285 "Modified: 16.1.1997 / 19:33:49 / cg" |
1285 "Modified: 16.1.1997 / 19:33:49 / cg" |
1286 ! ! |
1286 ! ! |
1287 |
1287 |
1296 separate directory, thereby overriding system bitmaps easily. |
1296 separate directory, thereby overriding system bitmaps easily. |
1297 If the file is unreadable or does not contain an appropriate image, |
1297 If the file is unreadable or does not contain an appropriate image, |
1298 the ImageNotFoundQuerySignal is raised, which may be handled to |
1298 the ImageNotFoundQuerySignal is raised, which may be handled to |
1299 proceed with some replacement image. If unhandled, nil is returned." |
1299 proceed with some replacement image. If unhandled, nil is returned." |
1300 |
1300 |
1301 |image name fn nm inStream suffix readerClass |
1301 |image name fn nm inStream suffix readerClass |
1302 mustDecompress inPipe readersErrorMsg| |
1302 mustDecompress inPipe readersErrorMsg| |
1303 |
1303 |
1304 "before trying each reader, check if the file is readable" |
1304 "before trying each reader, check if the file is readable" |
1305 |
1305 |
1306 name := aFileName asFilename. |
1306 name := aFileName asFilename. |
1307 |
1307 |
1308 inStream := Smalltalk systemFileStreamFor:name. |
1308 inStream := Smalltalk systemFileStreamFor:name. |
1309 inStream isNil ifTrue:[ |
1309 inStream isNil ifTrue:[ |
1310 inStream := Smalltalk bitmapFileStreamFor:name. |
1310 inStream := Smalltalk bitmapFileStreamFor:name. |
1311 inStream isNil ifTrue:[ |
1311 inStream isNil ifTrue:[ |
1312 "this signal is a query - if noone seems to care, return nil. |
1312 "this signal is a query - if noone seems to care, return nil. |
1313 However, a handler may provide a replacement image." |
1313 However, a handler may provide a replacement image." |
1314 ^ ImageNotFoundQuerySignal |
1314 ^ ImageNotFoundQuerySignal |
1315 raiseRequestWith:aFileName |
1315 raiseRequestWith:aFileName |
1316 errorString:('IMAGE [warning]: ''' , name pathName, ''' does not exist or is not readable'). |
1316 errorString:('IMAGE [warning]: ''' , name pathName, ''' does not exist or is not readable'). |
1317 ]. |
1317 ]. |
1318 ]. |
1318 ]. |
1319 fn := inStream pathName asFilename. |
1319 fn := inStream pathName asFilename. |
1320 inStream close. |
1320 inStream close. |
1321 |
1321 |
1322 nm := fn name. |
1322 nm := fn name. |
1323 suffix := fn suffix. |
1323 suffix := fn suffix. |
1324 |
1324 |
1325 "handle compressed-suffix" |
1325 "handle compressed-suffix" |
1326 (#('Z' 'gz') includes:suffix) ifTrue:[ |
1326 (#('Z' 'gz') includes:suffix) ifTrue:[ |
1327 fn := fn withoutSuffix. |
1327 fn := fn withoutSuffix. |
1328 nm := fn name. |
1328 nm := fn name. |
1329 suffix := fn suffix. |
1329 suffix := fn suffix. |
1330 mustDecompress := true. |
1330 mustDecompress := true. |
1331 ]. |
1331 ]. |
1332 suffix isEmpty ifTrue:[ |
1332 suffix isEmpty ifTrue:[ |
1333 suffix := nm. |
1333 suffix := nm. |
1334 ]. |
1334 ]. |
1335 |
1335 |
1336 "get the imageReader class from the files extension and ask it first" |
1336 "get the imageReader class from the files extension and ask it first" |
1337 readerClass := MIMETypes imageReaderForSuffix:suffix. |
1337 readerClass := MIMETypes imageReaderForSuffix:suffix. |
1338 readerClass notNil ifTrue:[ |
1338 readerClass notNil ifTrue:[ |
1339 mustDecompress == true ifTrue:[ |
1339 mustDecompress == true ifTrue:[ |
1340 inPipe := PipeStream readingFrom:'gunzip <' , fn pathName. |
1340 inPipe := PipeStream readingFrom:'gunzip <' , fn pathName. |
1341 inPipe notNil ifTrue:[ |
1341 inPipe notNil ifTrue:[ |
1342 [ |
1342 [ |
1343 image := readerClass fromStream:inPipe. |
1343 image := readerClass fromStream:inPipe. |
1344 ] ensure:[ |
1344 ] ensure:[ |
1345 inPipe close |
1345 inPipe close |
1346 ]. |
1346 ]. |
1347 ] |
1347 ] |
1348 ] ifFalse:[ |
1348 ] ifFalse:[ |
1349 BadImageFormatQuerySignal handle:[:ex | |
1349 BadImageFormatQuerySignal handle:[:ex | |
1350 Transcript showCR:(readersErrorMsg := ex description). |
1350 Transcript showCR:(readersErrorMsg := ex description). |
1351 image := nil. |
1351 image := nil. |
1352 ex return. |
1352 ex return. |
1353 ] do:[ |
1353 ] do:[ |
1354 image := readerClass fromFile:fn. |
1354 image := readerClass fromFile:fn. |
1355 ]. |
1355 ]. |
1356 ]. |
1356 ]. |
1357 image notNil ifTrue:[^ image]. |
1357 image notNil ifTrue:[^ image]. |
1358 ]. |
1358 ]. |
1359 |
1359 |
1360 (readerClass isNil or:[readersErrorMsg notNil]) ifTrue:[ |
1360 (readerClass isNil or:[readersErrorMsg notNil]) ifTrue:[ |
1361 "no known extension (or wrong extension) |
1361 "no known extension (or wrong extension) |
1362 - ask all readers if they know this format ... |
1362 - ask all readers if they know this format ... |
1363 ... these look into the file, and investigate the header. |
1363 ... these look into the file, and investigate the header. |
1364 therefore, it takes a bit longer." |
1364 therefore, it takes a bit longer." |
1365 |
1365 |
1366 MIMETypes imageReaderClasses do:[:mimeReaderClass | |
1366 MIMETypes imageReaderClasses do:[:mimeReaderClass | |
1367 (mimeReaderClass notNil |
1367 (mimeReaderClass notNil |
1368 and:[mimeReaderClass ~~ readerClass]) ifTrue:[ |
1368 and:[mimeReaderClass ~~ readerClass]) ifTrue:[ |
1369 (mimeReaderClass isValidImageFile:name) ifTrue:[ |
1369 (mimeReaderClass isValidImageFile:name) ifTrue:[ |
1370 image := mimeReaderClass fromFile:name. |
1370 image := mimeReaderClass fromFile:name. |
1371 image notNil ifTrue:[ |
1371 image notNil ifTrue:[ |
1372 ^ image |
1372 ^ image |
1373 ] |
1373 ] |
1374 ] |
1374 ] |
1375 ] |
1375 ] |
1376 ]. |
1376 ]. |
1377 ]. |
1377 ]. |
1378 |
1378 |
1379 "nope - unknown format |
1379 "nope - unknown format |
1380 this signal is a query - if noone seems to care, return nil. |
1380 this signal is a query - if noone seems to care, return nil. |
1381 However, a handler may provide a replacement image." |
1381 However, a handler may provide a replacement image." |
1382 |
1382 |
1383 ^ BadImageFormatQuerySignal |
1383 ^ BadImageFormatQuerySignal |
1384 raiseRequestWith:aFileName |
1384 raiseRequestWith:aFileName |
1385 errorString:(readersErrorMsg ? ('IMAGE [warning]: unknown image file format: ''' , aFileName asFilename pathName , '''')). |
1385 errorString:(readersErrorMsg ? ('IMAGE [warning]: unknown image file format: ''' , aFileName asFilename pathName , '''')). |
1386 |
1386 |
1387 " |
1387 " |
1388 Image fromFile:'goodies/bitmaps/gifImages/claus.gif' |
1388 Image fromFile:'goodies/bitmaps/gifImages/claus.gif' |
1389 Image fromFile:'goodies/bitmaps/gifImages/garfield.gif' |
1389 Image fromFile:'goodies/bitmaps/gifImages/garfield.gif' |
1390 |
1390 |
1398 Image fromFile:'fooBar' |
1398 Image fromFile:'fooBar' |
1399 " |
1399 " |
1400 |
1400 |
1401 "giving a message for non-existing images: |
1401 "giving a message for non-existing images: |
1402 |
1402 |
1403 Image imageNotFoundQuerySignal |
1403 Image imageNotFoundQuerySignal |
1404 handle:[:ex | |
1404 handle:[:ex | |
1405 Transcript showCR:ex description. |
1405 Transcript showCR:ex description. |
1406 ex proceedWith:nil |
1406 ex proceedWith:nil |
1407 ] do:[ |
1407 ] do:[ |
1408 Image fromFile:'fooBar' |
1408 Image fromFile:'fooBar' |
1409 ] |
1409 ] |
1410 " |
1410 " |
1411 |
1411 |
1412 "giving a replacement for non-existing images: |
1412 "giving a replacement for non-existing images: |
1413 |
1413 |
1414 Image imageNotFoundQuerySignal |
1414 Image imageNotFoundQuerySignal |
1415 answer:(Image fromFile:'libtool/bitmaps/SmalltalkX.xbm') |
1415 answer:(Image fromFile:'libtool/bitmaps/SmalltalkX.xbm') |
1416 do:[ |
1416 do:[ |
1417 Image fromFile:'fooBar' |
1417 Image fromFile:'fooBar' |
1418 ] |
1418 ] |
1419 " |
1419 " |
1420 |
1420 |
1421 "Modified: / 18.5.1999 / 15:48:20 / cg" |
1421 "Modified: / 18.5.1999 / 15:48:20 / cg" |
1422 ! |
1422 ! |
1442 " |
1442 " |
1443 ! |
1443 ! |
1444 |
1444 |
1445 fromFile:aFileName on:aDevice |
1445 fromFile:aFileName on:aDevice |
1446 "read an image from a file and prepare a device representation. |
1446 "read an image from a file and prepare a device representation. |
1447 Return nil (or whatever a handler returned), |
1447 Return nil (or whatever a handler returned), |
1448 if the file is unreadable or does not contain an appropriate image." |
1448 if the file is unreadable or does not contain an appropriate image." |
1449 |
1449 |
1450 |img| |
1450 |img| |
1451 |
1451 |
1452 img := self fromFile:aFileName. |
1452 img := self fromFile:aFileName. |
1459 ! |
1459 ! |
1460 |
1460 |
1461 fromFile:aFileName resolution:res |
1461 fromFile:aFileName resolution:res |
1462 "read an image from a file and (if required) scale the image |
1462 "read an image from a file and (if required) scale the image |
1463 as appropriate (only req'd for very high resolution displays). |
1463 as appropriate (only req'd for very high resolution displays). |
1464 Return nil (or whatever a handler returned), |
1464 Return nil (or whatever a handler returned), |
1465 if the file is unreadable or does not contain an appropriate image." |
1465 if the file is unreadable or does not contain an appropriate image." |
1466 |
1466 |
1467 ^ self fromFile:aFileName resolution:res on:nil |
1467 ^ self fromFile:aFileName resolution:res on:nil |
1468 |
1468 |
1469 "Created: 19.12.1996 / 14:02:13 / cg" |
1469 "Created: 19.12.1996 / 14:02:13 / cg" |
1472 |
1472 |
1473 fromFile:aFileName resolution:dpi on:aDevice |
1473 fromFile:aFileName resolution:dpi on:aDevice |
1474 "read an image from a file and (if required) scale the image |
1474 "read an image from a file and (if required) scale the image |
1475 as appropriate (only req'd with very high resolution displays). |
1475 as appropriate (only req'd with very high resolution displays). |
1476 Prepare a device representation. |
1476 Prepare a device representation. |
1477 Return nil (or whatever a handler returned), |
1477 Return nil (or whatever a handler returned), |
1478 if the file is unreadable or does not contain an appropriate image." |
1478 if the file is unreadable or does not contain an appropriate image." |
1479 |
1479 |
1480 |img dev dpiH mag| |
1480 |img dev dpiH mag| |
1481 |
1481 |
1482 img := self fromFile:aFileName. |
1482 img := self fromFile:aFileName. |
1511 fromStream:aStream |
1511 fromStream:aStream |
1512 "read an image from a stream - this methods tries to find |
1512 "read an image from a stream - this methods tries to find |
1513 out the file format itself (by contents) |
1513 out the file format itself (by contents) |
1514 and lets the appropriate reader read the file. |
1514 and lets the appropriate reader read the file. |
1515 To do this, the stream must be positionable. |
1515 To do this, the stream must be positionable. |
1516 Return nil (or whatever a handler returned), |
1516 Return nil (or whatever a handler returned), |
1517 if the stream does not contain an appropriate image." |
1517 if the stream does not contain an appropriate image." |
1518 |
1518 |
1519 |image| |
1519 |image| |
1520 |
1520 |
1521 " |
1521 " |
1522 ask all readers if they know |
1522 ask all readers if they know |
1523 this format ... |
1523 this format ... |
1524 " |
1524 " |
1525 MIMETypes imageReaderClasses do:[:readerClass | |
1525 MIMETypes imageReaderClasses do:[:readerClass | |
1526 readerClass notNil ifTrue:[ |
1526 readerClass notNil ifTrue:[ |
1527 image := readerClass fromStream:aStream. |
1527 image := readerClass fromStream:aStream. |
1528 image notNil ifTrue:[^ image]. |
1528 image notNil ifTrue:[^ image]. |
1529 ] |
1529 ] |
1530 ]. |
1530 ]. |
1531 |
1531 |
1532 " |
1532 " |
1533 nope - unknown format |
1533 nope - unknown format |
1534 " |
1534 " |
1535 "/ 'Image [info]: unknown image file format in stream: ' infoPrintCR. |
1535 "/ 'Image [info]: unknown image file format in stream: ' infoPrintCR. |
1536 |
1536 |
1537 ^ ImageNotFoundQuerySignal |
1537 ^ ImageNotFoundQuerySignal |
1538 raiseRequestWith:aStream |
1538 raiseRequestWith:aStream |
1539 errorString:('IMAGE [warning]: unknown image file format in stream'). |
1539 errorString:('IMAGE [warning]: unknown image file format in stream'). |
1540 |
1540 |
1541 " |
1541 " |
1542 Image fromFile:'goodies/bitmaps/gifImages/claus.gif' |
1542 Image fromFile:'goodies/bitmaps/gifImages/claus.gif' |
1543 Image fromFile:'goodies/bitmaps/gifImages/garfield.gif' |
1543 Image fromFile:'goodies/bitmaps/gifImages/garfield.gif' |
1544 |
1544 |
1561 fromStream:aStream using:aReaderClass |
1561 fromStream:aStream using:aReaderClass |
1562 "read an image from a stream, given an imageReaderClass. |
1562 "read an image from a stream, given an imageReaderClass. |
1563 Use this, if you know the files format, but it has an invalid |
1563 Use this, if you know the files format, but it has an invalid |
1564 extension (or non-definite header), so #fromStream: could not |
1564 extension (or non-definite header), so #fromStream: could not |
1565 find out the images format. |
1565 find out the images format. |
1566 Return nil (or whatever a handler returned), |
1566 Return nil (or whatever a handler returned), |
1567 if the stream does not contain an appropriate image." |
1567 if the stream does not contain an appropriate image." |
1568 |
1568 |
1569 |image| |
1569 |image| |
1570 |
1570 |
1571 image := aReaderClass fromStream:aStream. |
1571 image := aReaderClass fromStream:aStream. |
1585 ! ! |
1585 ! ! |
1586 |
1586 |
1587 !Image class methodsFor:'misc'! |
1587 !Image class methodsFor:'misc'! |
1588 |
1588 |
1589 ditherAlgorithm |
1589 ditherAlgorithm |
1590 "return the way we dither - |
1590 "return the way we dither - |
1591 #threshold, or nil -> no dither |
1591 #threshold, or nil -> no dither |
1592 #pattern, or #ordered -> orderedDither (ugly, but fast) |
1592 #pattern, or #ordered -> orderedDither (ugly, but fast) |
1593 #error or #floydSteinberg -> errorDiffusion; much better |
1593 #error or #floydSteinberg -> errorDiffusion; much better |
1594 #burkes -> errorDiffusion; even better." |
1594 #burkes -> errorDiffusion; even better." |
1595 |
1595 |
1597 |
1597 |
1598 "Created: 17.6.1996 / 18:57:47 / cg" |
1598 "Created: 17.6.1996 / 18:57:47 / cg" |
1599 ! |
1599 ! |
1600 |
1600 |
1601 ditherAlgorithm:aSymbol |
1601 ditherAlgorithm:aSymbol |
1602 "define how to dither - |
1602 "define how to dither - |
1603 #threshold, or nil -> no dither |
1603 #threshold, or nil -> no dither |
1604 #pattern, or #ordered -> orderedDither (ugly, but fast) |
1604 #pattern, or #ordered -> orderedDither (ugly, but fast) |
1605 #error or #floydSteinberg -> errorDiffusion; much better |
1605 #error or #floydSteinberg -> errorDiffusion; much better |
1606 #burkes -> errorDiffusion; even better." |
1606 #burkes -> errorDiffusion; even better." |
1607 |
1607 |
1626 ! |
1626 ! |
1627 |
1627 |
1628 orderedDitherMatrixOfSize:sz |
1628 orderedDitherMatrixOfSize:sz |
1629 sz == 2 ifTrue:[ |
1629 sz == 2 ifTrue:[ |
1630 ^ #[ |
1630 ^ #[ |
1631 0 2 |
1631 0 2 |
1632 3 1 |
1632 3 1 |
1633 ]. |
1633 ]. |
1634 ]. |
1634 ]. |
1635 |
1635 |
1636 sz == 4 ifTrue:[ |
1636 sz == 4 ifTrue:[ |
1644 |
1644 |
1645 sz == 8 ifTrue:[ |
1645 sz == 8 ifTrue:[ |
1646 ^ #[ |
1646 ^ #[ |
1647 0 32 8 40 2 34 10 42 |
1647 0 32 8 40 2 34 10 42 |
1648 48 16 56 24 50 18 58 26 |
1648 48 16 56 24 50 18 58 26 |
1649 12 44 4 36 14 46 6 38 |
1649 12 44 4 36 14 46 6 38 |
1650 60 28 52 20 62 30 54 22 |
1650 60 28 52 20 62 30 54 22 |
1651 |
1651 |
1652 3 35 11 43 1 33 9 41 |
1652 3 35 11 43 1 33 9 41 |
1653 51 19 59 27 49 17 57 25 |
1653 51 19 59 27 49 17 57 25 |
1654 15 47 7 39 13 45 5 37 |
1654 15 47 7 39 13 45 5 37 |
1655 63 31 55 23 61 29 53 21 |
1655 63 31 55 23 61 29 53 21 |
1656 ]. |
1656 ]. |
1657 ]. |
1657 ]. |
1658 |
1658 |
1659 ^ nil |
1659 ^ nil |
1773 return it; return nil if unknown" |
1773 return it; return nil if unknown" |
1774 |
1774 |
1775 ^ MIMETypes mimeTypeForSuffix:suffix |
1775 ^ MIMETypes mimeTypeForSuffix:suffix |
1776 |
1776 |
1777 " |
1777 " |
1778 Image mimeTypeFromSuffix:'gif' |
1778 Image mimeTypeFromSuffix:'gif' |
1779 Image mimeTypeFromSuffix:'tiff' |
1779 Image mimeTypeFromSuffix:'tiff' |
1780 Image mimeTypeFromSuffix:'foobar' |
1780 Image mimeTypeFromSuffix:'foobar' |
1781 " |
1781 " |
1782 |
1782 |
1783 "Modified: 1.7.1997 / 00:17:27 / cg" |
1783 "Modified: 1.7.1997 / 00:17:27 / cg" |
1784 ! ! |
1784 ! ! |
1785 |
1785 |
1792 (use #fromScreen:on:grab: with a false grabArg then)." |
1792 (use #fromScreen:on:grab: with a false grabArg then)." |
1793 |
1793 |
1794 |display| |
1794 |display| |
1795 |
1795 |
1796 display := Screen current. |
1796 display := Screen current. |
1797 ^ self |
1797 ^ self |
1798 fromScreen:(0@0 corner:(display width @ display height)) |
1798 fromScreen:(0@0 corner:(display width @ display height)) |
1799 on:display |
1799 on:display |
1800 grab:true |
1800 grab:true |
1801 |
1801 |
1802 " |
1802 " |
1811 "return an image of a part of the screen. |
1811 "return an image of a part of the screen. |
1812 WARNING: this temporarily grabs the display |
1812 WARNING: this temporarily grabs the display |
1813 it may not work from within a buttonMotion |
1813 it may not work from within a buttonMotion |
1814 (use #fromScreen:on:grab: with a false grabArg then)." |
1814 (use #fromScreen:on:grab: with a false grabArg then)." |
1815 |
1815 |
1816 ^ self |
1816 ^ self |
1817 fromScreen:aRectangle |
1817 fromScreen:aRectangle |
1818 on:Screen current |
1818 on:Screen current |
1819 grab:true |
1819 grab:true |
1820 |
1820 |
1821 " |
1821 " |
1822 Image fromScreen:(0@0 corner:100@100) |
1822 Image fromScreen:(0@0 corner:100@100) |
1832 WARNING: this temporarily grabs the display |
1832 WARNING: this temporarily grabs the display |
1833 it may not work from within a buttonMotion |
1833 it may not work from within a buttonMotion |
1834 (use #fromScreen:on:grab: with a false grabArg then)." |
1834 (use #fromScreen:on:grab: with a false grabArg then)." |
1835 |
1835 |
1836 ^ self |
1836 ^ self |
1837 fromScreen:aRectangle |
1837 fromScreen:aRectangle |
1838 on:aDevice |
1838 on:aDevice |
1839 grab:true |
1839 grab:true |
1840 |
1840 |
1841 " |
1841 " |
1842 Image fromScreen:(0@0 corner:100@100) |
1842 Image fromScreen:(0@0 corner:100@100) |
1843 " |
1843 " |
1857 "return an image of a part of the screen, which may be on |
1857 "return an image of a part of the screen, which may be on |
1858 another Display. If the doGrab argument is true, the display |
1858 another Display. If the doGrab argument is true, the display |
1859 is grabbed (i.e. blocked for others) and a camera cursor is |
1859 is grabbed (i.e. blocked for others) and a camera cursor is |
1860 shown while the readout is done. |
1860 shown while the readout is done. |
1861 WARNING: with doGrab true, this temporarily grabs the display |
1861 WARNING: with doGrab true, this temporarily grabs the display |
1862 and it may not work from within a buttonMotion |
1862 and it may not work from within a buttonMotion |
1863 (use with a false grabArg then)." |
1863 (use with a false grabArg then)." |
1864 |
1864 |
1865 |depth vis img| |
1865 |depth vis img| |
1866 |
1866 |
1867 depth := aDisplay depth. |
1867 depth := aDisplay depth. |
1868 |
1868 |
1871 "/ (must do this for depth15 & depth16 displays, since |
1871 "/ (must do this for depth15 & depth16 displays, since |
1872 "/ Depth16Image has no way to specify r/g/b masks ...) |
1872 "/ Depth16Image has no way to specify r/g/b masks ...) |
1873 "/ |
1873 "/ |
1874 vis := aDisplay visualType. |
1874 vis := aDisplay visualType. |
1875 (vis == #TrueColor or:[vis == #DirectColor]) ifTrue:[ |
1875 (vis == #TrueColor or:[vis == #DirectColor]) ifTrue:[ |
1876 depth > 8 ifTrue:[ |
1876 depth > 8 ifTrue:[ |
1877 depth := 24. |
1877 depth := 24. |
1878 ] |
1878 ] |
1879 ]. |
1879 ]. |
1880 |
1880 |
1881 img := self newForDepth:depth. |
1881 img := self newForDepth:depth. |
1882 ^ img fromScreen:aRectangle on:aDisplay grab:doGrab |
1882 ^ img fromScreen:aRectangle on:aDisplay grab:doGrab |
1883 |
1883 |
1884 "Modified: / 26.1.1998 / 22:23:08 / cg" |
1884 "Modified: / 26.1.1998 / 22:23:08 / cg" |
1885 ! |
1885 ! |
1886 |
1886 |
1887 fromScreenArea |
1887 fromScreenArea |
1888 "return an image of a part of the screen; |
1888 "return an image of a part of the screen; |
1889 let user specify screen area. |
1889 let user specify screen area. |
1890 This is the same as #fromUser - kept for backward compatibility. |
1890 This is the same as #fromUser - kept for backward compatibility. |
1891 Use #fromUser for ST-80 compatibility. |
1891 Use #fromUser for ST-80 compatibility. |
1892 WARNING: this temporarily grabs the display |
1892 WARNING: this temporarily grabs the display |
1893 it may not work from within a buttonMotion |
1893 it may not work from within a buttonMotion |
1927 ! |
1927 ! |
1928 |
1928 |
1929 fromView:aView |
1929 fromView:aView |
1930 "return an image taken from a views contents as currently |
1930 "return an image taken from a views contents as currently |
1931 on the screen. The returned image has the same depth and photometric |
1931 on the screen. The returned image has the same depth and photometric |
1932 as the Display. |
1932 as the Display. |
1933 Notice, that for invisible or partial covered views, |
1933 Notice, that for invisible or partial covered views, |
1934 the returned Image is NOT correct. |
1934 the returned Image is NOT correct. |
1935 You may want to raise the view before using this method. |
1935 You may want to raise the view before using this method. |
1936 WARNING: this temporarily grabs the display |
1936 WARNING: this temporarily grabs the display |
1937 it may not work from within a buttonMotion |
1937 it may not work from within a buttonMotion |
1938 (use #fromView:grab: with a false grabArg then)." |
1938 (use #fromView:grab: with a false grabArg then)." |
1939 |
1939 |
1940 ^ self |
1940 ^ self |
1941 fromView:aView |
1941 fromView:aView |
1942 grab:true |
1942 grab:true |
1943 |
1943 |
1944 " |
1944 " |
1945 Image fromView:(Launcher allInstances first window topView) |
1945 Image fromView:(Launcher allInstances first window topView) |
1946 Image fromView:(BrowserView allInstances first topView) |
1946 Image fromView:(BrowserView allInstances first topView) |
1962 "return an image taken from a views contents as currently |
1962 "return an image taken from a views contents as currently |
1963 on the screen. If the doGrab argument is true, the display |
1963 on the screen. If the doGrab argument is true, the display |
1964 is grabbed (i.e. blocked for others) and a camera cursor is |
1964 is grabbed (i.e. blocked for others) and a camera cursor is |
1965 shown while the readout is done. |
1965 shown while the readout is done. |
1966 The returned image has the same depth and photometric |
1966 The returned image has the same depth and photometric |
1967 as the Display. |
1967 as the Display. |
1968 Notice, that for invisible or partial covered views, |
1968 Notice, that for invisible or partial covered views, |
1969 the returned Image is NOT correct. |
1969 the returned Image is NOT correct. |
1970 You may want to raise the view before using this method. |
1970 You may want to raise the view before using this method. |
1971 WARNING: with doGrab true, this temporarily grabs the display |
1971 WARNING: with doGrab true, this temporarily grabs the display |
1972 and it may not work from within a buttonMotion |
1972 and it may not work from within a buttonMotion |
1973 (use with a false grabArg then)." |
1973 (use with a false grabArg then)." |
1974 |
1974 |
1975 ^ self fromView:aView grab:doGrab withDecoration:false |
1975 ^ self fromView:aView grab:doGrab withDecoration:false |
1976 |
1976 |
1977 "Created: / 26.3.1997 / 10:34:20 / cg" |
1977 "Created: / 26.3.1997 / 10:34:20 / cg" |
1978 "Modified: / 10.10.2001 / 14:13:29 / cg" |
1978 "Modified: / 10.10.2001 / 14:13:29 / cg" |
1979 ! |
1979 ! |
1980 |
1980 |
1981 fromView:aView grab:doGrab withDecoration:withDecoration |
1981 fromView:aView grab:doGrab withDecoration:withDecoration |
1982 "return an image taken from a views contents as currently |
1982 "return an image taken from a views contents as currently |
1983 on the screen, optionally with decoration included. |
1983 on the screen, optionally with decoration included. |
1984 If the doGrab argument is true, the display |
1984 If the doGrab argument is true, the display |
1985 is grabbed (i.e. blocked for others) and a camera cursor is |
1985 is grabbed (i.e. blocked for others) and a camera cursor is |
1986 shown while the readout is done. |
1986 shown while the readout is done. |
1987 The returned image has the same depth and photometric |
1987 The returned image has the same depth and photometric |
1988 as the Display. |
1988 as the Display. |
1989 Notice, that for invisible or partial covered views, |
1989 Notice, that for invisible or partial covered views, |
1990 the returned Image is NOT correct. |
1990 the returned Image is NOT correct. |
1991 You may want to raise the view before using this method. |
1991 You may want to raise the view before using this method. |
1992 WARNING: with doGrab true, this temporarily grabs the display |
1992 WARNING: with doGrab true, this temporarily grabs the display |
1993 and it may not work from within a buttonMotion |
1993 and it may not work from within a buttonMotion |
1994 (use with a false grabArg then)." |
1994 (use with a false grabArg then)." |
1995 |
1995 |
1996 |org ext device cH bW bH| |
1996 |org ext device cH bW bH| |
1997 |
1997 |
1998 device := aView graphicsDevice. |
1998 device := aView graphicsDevice. |
1999 org := device translatePoint:(0@0) fromView:aView toView:nil. |
1999 org := device translatePoint:(0@0) fromView:aView toView:nil. |
2000 ext := aView extent. |
2000 ext := aView extent. |
2001 withDecoration ifTrue:[ |
2001 withDecoration ifTrue:[ |
2002 device platformName = 'WIN32' ifTrue:[ |
2002 device platformName = 'WIN32' ifTrue:[ |
2003 cH := device captionHeight. |
2003 cH := device captionHeight. |
2004 bW := (device getSystemMetrics: #SM_CXFRAME ) |
2004 bW := (device getSystemMetrics: #SM_CXFRAME ) |
2005 "+ ( device getSystemMetrics: #borderFrameWidth )". |
2005 "+ ( device getSystemMetrics: #borderFrameWidth )". |
2006 bH := (device getSystemMetrics: #SM_CYFRAME ) |
2006 bH := (device getSystemMetrics: #SM_CYFRAME ) |
2007 " + ( device getSystemMetrics: #borderFrameHeight )". |
2007 " + ( device getSystemMetrics: #borderFrameHeight )". |
2008 org := org - (bW @ (bH + cH)). |
2008 org := org - (bW @ (bH + cH)). |
2009 ext := ext + ((bW + bW) @ (bH+bH+cH)). |
2009 ext := ext + ((bW + bW) @ (bH+bH+cH)). |
2010 ]. |
2010 ]. |
2011 ]. |
2011 ]. |
2012 ^ self fromScreen:(org extent:ext) on:device grab:doGrab |
2012 ^ self fromScreen:(org extent:ext) on:device grab:doGrab |
2013 |
2013 |
2014 " |
2014 " |
2015 Transcript topView raise. (Image fromView:Transcript topView grab:false withDecoration:false) inspect |
2015 Transcript topView raise. (Image fromView:Transcript topView grab:false withDecoration:false) inspect |
2016 Transcript topView raise. (Image fromView:Transcript topView grab:false withDecoration:true) inspect |
2016 Transcript topView raise. (Image fromView:Transcript topView grab:false withDecoration:true) inspect |
2017 " |
2017 " |
2018 |
2018 |
2019 "Created: / 26-03-1997 / 10:34:20 / cg" |
2019 "Created: / 26-03-1997 / 10:34:20 / cg" |
2020 "Modified: / 08-09-2006 / 15:41:41 / cg" |
2020 "Modified: / 08-09-2006 / 15:41:41 / cg" |
2021 ! ! |
2021 ! ! |
2046 |
2046 |
2047 " |
2047 " |
2048 |img| |
2048 |img| |
2049 img := Image extent:100@100 depth:24. |
2049 img := Image extent:100@100 depth:24. |
2050 img photometric:#rgb. |
2050 img photometric:#rgb. |
2051 img data:(ByteArray new:100*100*3). |
2051 img data:(ByteArray new:100*100*3). |
2052 img fillWhite:(0@0 corner:100@100). |
2052 img fillWhite:(0@0 corner:100@100). |
2053 img fillBlack:(10@10 corner:90@90). |
2053 img fillBlack:(10@10 corner:90@90). |
2054 img inspect. |
2054 img inspect. |
2055 " |
2055 " |
2056 ! |
2056 ! |
2068 |
2068 |
2069 !Image methodsFor:'Compatibility-VW'! |
2069 !Image methodsFor:'Compatibility-VW'! |
2070 |
2070 |
2071 asCachedImage |
2071 asCachedImage |
2072 "return the receiver associated to the current screens device. |
2072 "return the receiver associated to the current screens device. |
2073 For ST-80 compatibility |
2073 For ST-80 compatibility |
2074 (ST/X uses Image for both device- and nonDevice-images)" |
2074 (ST/X uses Image for both device- and nonDevice-images)" |
2075 |
2075 |
2076 ^ self onDevice:Screen current |
2076 ^ self onDevice:Screen current |
2077 |
2077 |
2078 "Modified: 23.4.1996 / 11:10:32 / cg" |
2078 "Modified: 23.4.1996 / 11:10:32 / cg" |
2079 ! |
2079 ! |
2080 |
2080 |
2081 asRetainedMedium |
2081 asRetainedMedium |
2082 "return the receiver associated to the current screens device. |
2082 "return the receiver associated to the current screens device. |
2083 For ST-80 compatibility |
2083 For ST-80 compatibility |
2084 (ST/X uses Image for both device- and nonDevice-images)" |
2084 (ST/X uses Image for both device- and nonDevice-images)" |
2085 |
2085 |
2086 ^ self onDevice:Screen current |
2086 ^ self onDevice:Screen current |
2087 |
2087 |
2088 "Modified: 23.4.1996 / 11:10:32 / cg" |
2088 "Modified: 23.4.1996 / 11:10:32 / cg" |
2152 |
2152 |
2153 tile:bounds from:origin in:tile rule:rule |
2153 tile:bounds from:origin in:tile rule:rule |
2154 |orgX orgY tW tH| |
2154 |orgX orgY tW tH| |
2155 |
2155 |
2156 origin ~= (0@0) ifTrue:[ |
2156 origin ~= (0@0) ifTrue:[ |
2157 self halt:'unimplemented'. |
2157 self halt:'unimplemented'. |
2158 ]. |
2158 ]. |
2159 bounds ~= self bounds ifTrue:[ |
2159 bounds ~= self bounds ifTrue:[ |
2160 self halt:'unimplemented'. |
2160 self halt:'unimplemented'. |
2161 ]. |
2161 ]. |
2162 rule ~= #over ifTrue:[ |
2162 rule ~= #over ifTrue:[ |
2163 self halt:'unimplemented'. |
2163 self halt:'unimplemented'. |
2164 ]. |
2164 ]. |
2165 |
2165 |
2166 orgX := origin x. |
2166 orgX := origin x. |
2167 orgY := origin y. |
2167 orgY := origin y. |
2168 tW := tile width. |
2168 tW := tile width. |
2169 tH := tile height. |
2169 tH := tile height. |
2170 (bounds top) to:(bounds bottom) by:tH do:[:dstY | |
2170 (bounds top) to:(bounds bottom) by:tH do:[:dstY | |
2171 (bounds left) to:(bounds right) by:(tile width) do:[:dstX | |
2171 (bounds left) to:(bounds right) by:(tile width) do:[:dstX | |
2172 self |
2172 self |
2173 copyFrom:tile |
2173 copyFrom:tile |
2174 x:orgX y:orgY |
2174 x:orgX y:orgY |
2175 toX:dstX y:dstY |
2175 toX:dstX y:dstY |
2176 width:tW height:tH. |
2176 width:tW height:tH. |
2177 ]. |
2177 ]. |
2178 ]. |
2178 ]. |
2179 ! |
2179 ! |
2180 |
2180 |
2181 valueAtPoint:aPoint put:aColorValue |
2181 valueAtPoint:aPoint put:aColorValue |
2182 aColorValue isInteger ifFalse:[ |
2182 aColorValue isInteger ifFalse:[ |
2183 self colorAtX:aPoint x y:aPoint y put:aColorValue |
2183 self colorAtX:aPoint x y:aPoint y put:aColorValue |
2184 ] ifTrue:[ |
2184 ] ifTrue:[ |
2185 self pixelAtX:aPoint x y:aPoint y put:aColorValue |
2185 self pixelAtX:aPoint x y:aPoint y put:aColorValue |
2186 ] |
2186 ] |
2187 ! ! |
2187 ! ! |
2188 |
2188 |
2189 !Image methodsFor:'accessing'! |
2189 !Image methodsFor:'accessing'! |
2190 |
2190 |
2408 |
2408 |
2409 monoDeviceForm isNil ifTrue:[^ nil]. |
2409 monoDeviceForm isNil ifTrue:[^ nil]. |
2410 ^ monoDeviceForm id |
2410 ^ monoDeviceForm id |
2411 ! |
2411 ! |
2412 |
2412 |
2413 palette |
2413 palette |
2414 "return the colormap; ST-80 compatibility" |
2414 "return the colormap; ST-80 compatibility" |
2415 |
2415 |
2416 ^ colorMap |
2416 ^ colorMap |
2417 ! |
2417 ! |
2418 |
2418 |
2419 palette:aColormap |
2419 palette:aColormap |
2420 "set the colormap; ST-80 compatibility" |
2420 "set the colormap; ST-80 compatibility" |
2421 |
2421 |
2422 self colorMap:aColormap |
2422 self colorMap:aColormap |
2423 |
2423 |
2424 "Created: 1.2.1996 / 15:09:25 / cg" |
2424 "Created: 1.2.1996 / 15:09:25 / cg" |
2456 ! ! |
2456 ! ! |
2457 |
2457 |
2458 !Image methodsFor:'accessing-pixels'! |
2458 !Image methodsFor:'accessing-pixels'! |
2459 |
2459 |
2460 at:aPoint |
2460 at:aPoint |
2461 "WARNING: for now, this returns a pixels color |
2461 "WARNING: for now, this returns a pixels color |
2462 (backward compatibility with ST/X) |
2462 (backward compatibility with ST/X) |
2463 In the future, this will return a pixel value (ST-80 compatibility) |
2463 In the future, this will return a pixel value (ST-80 compatibility) |
2464 Use #colorAt: - for future compatibility. |
2464 Use #colorAt: - for future compatibility. |
2465 |
2465 |
2466 retrieve the pixel at aPoint; return a color. |
2466 retrieve the pixel at aPoint; return a color. |
2478 "Modified: / 21.6.1997 / 13:10:17 / cg" |
2478 "Modified: / 21.6.1997 / 13:10:17 / cg" |
2479 "Modified: / 9.1.1998 / 20:33:52 / stefan" |
2479 "Modified: / 9.1.1998 / 20:33:52 / stefan" |
2480 ! |
2480 ! |
2481 |
2481 |
2482 at:aPoint put:aColor |
2482 at:aPoint put:aColor |
2483 "WARNING: for now, this expects a pixels color |
2483 "WARNING: for now, this expects a pixels color |
2484 (backward compatibility with ST/X) |
2484 (backward compatibility with ST/X) |
2485 In the future, this will expect a pixel value (ST-80 compatibility) |
2485 In the future, this will expect a pixel value (ST-80 compatibility) |
2486 Use #colorAt:put: - for future compatibility. |
2486 Use #colorAt:put: - for future compatibility. |
2487 |
2487 |
2488 set the pixel at aPoint to aColor. |
2488 set the pixel at aPoint to aColor. |
2507 otherwise to 1. Nil is treated like noColor. |
2507 otherwise to 1. Nil is treated like noColor. |
2508 (used by the bitmap editor)" |
2508 (used by the bitmap editor)" |
2509 |
2509 |
2510 |maskVal| |
2510 |maskVal| |
2511 |
2511 |
2512 (aColorOrPixelOrNil notNil and:[aColorOrPixelOrNil ~= Color noColor]) ifTrue:[ |
2512 (aColorOrPixelOrNil notNil and:[aColorOrPixelOrNil ~= Color noColor]) ifTrue:[ |
2513 maskVal := 1. |
2513 maskVal := 1. |
2514 aColorOrPixelOrNil isInteger ifTrue:[ |
2514 aColorOrPixelOrNil isInteger ifTrue:[ |
2515 self pixelAt:aPoint put:aColorOrPixelOrNil. |
2515 self pixelAt:aPoint put:aColorOrPixelOrNil. |
2516 ] ifFalse:[ |
2516 ] ifFalse:[ |
2517 self colorAt:aPoint put:aColorOrPixelOrNil |
2517 self colorAt:aPoint put:aColorOrPixelOrNil |
2520 maskVal := 0. |
2520 maskVal := 0. |
2521 self pixelAt:aPoint put:0. |
2521 self pixelAt:aPoint put:0. |
2522 ]. |
2522 ]. |
2523 mask notNil ifTrue:[ |
2523 mask notNil ifTrue:[ |
2524 mask pixelAt:aPoint put:maskVal |
2524 mask pixelAt:aPoint put:maskVal |
2525 ]. |
2525 ]. |
2526 |
2526 |
2527 "Modified: / 30.9.1998 / 22:42:44 / cg" |
2527 "Modified: / 30.9.1998 / 22:42:44 / cg" |
2528 ! |
2528 ! |
2529 |
2529 |
2530 atImageAndMask:aPoint putValue:aPixelValueOrNil |
2530 atImageAndMask:aPoint putValue:aPixelValueOrNil |
2533 otherwise to 1. |
2533 otherwise to 1. |
2534 (used by the bitmap editor)" |
2534 (used by the bitmap editor)" |
2535 |
2535 |
2536 |pixVal maskVal| |
2536 |pixVal maskVal| |
2537 |
2537 |
2538 aPixelValueOrNil notNil ifTrue:[ |
2538 aPixelValueOrNil notNil ifTrue:[ |
2539 pixVal := aPixelValueOrNil. |
2539 pixVal := aPixelValueOrNil. |
2540 maskVal := 1. |
2540 maskVal := 1. |
2541 ] ifFalse:[ |
2541 ] ifFalse:[ |
2542 pixVal := 0. |
2542 pixVal := 0. |
2543 maskVal := 0. |
2543 maskVal := 0. |
2544 ]. |
2544 ]. |
2545 mask notNil ifTrue:[ |
2545 mask notNil ifTrue:[ |
2546 mask pixelAt:aPoint put:maskVal |
2546 mask pixelAt:aPoint put:maskVal |
2547 ]. |
2547 ]. |
2548 self pixelAt:aPoint put:pixVal |
2548 self pixelAt:aPoint put:pixVal |
2549 |
2549 |
2550 "Modified: / 30.9.1998 / 22:42:44 / cg" |
2550 "Modified: / 30.9.1998 / 22:42:44 / cg" |
2551 ! |
2551 ! |
2552 |
2552 |
2565 |
2565 |
2566 "Modified: 24.4.1997 / 17:17:59 / cg" |
2566 "Modified: 24.4.1997 / 17:17:59 / cg" |
2567 ! |
2567 ! |
2568 |
2568 |
2569 atX:x y:y |
2569 atX:x y:y |
2570 "WARNING: for now, this returns a pixels color |
2570 "WARNING: for now, this returns a pixels color |
2571 (backward compatibility with ST/X) |
2571 (backward compatibility with ST/X) |
2572 In the future, this will return a pixel value (ST-80 compatibility) |
2572 In the future, this will return a pixel value (ST-80 compatibility) |
2573 Use #colorAt: - for future compatibility. |
2573 Use #colorAt: - for future compatibility. |
2574 |
2574 |
2575 Retrieve a pixel at x/y; return a color. |
2575 Retrieve a pixel at x/y; return a color. |
2584 |
2584 |
2585 "Modified: 21.6.1997 / 13:10:32 / cg" |
2585 "Modified: 21.6.1997 / 13:10:32 / cg" |
2586 ! |
2586 ! |
2587 |
2587 |
2588 atX:x y:y put:aColor |
2588 atX:x y:y put:aColor |
2589 "WARNING: for now, this expects a pixels color |
2589 "WARNING: for now, this expects a pixels color |
2590 (backward compatibility with ST/X) |
2590 (backward compatibility with ST/X) |
2591 In the future, this will expect a pixel value (ST-80 compatibility) |
2591 In the future, this will expect a pixel value (ST-80 compatibility) |
2592 Use #colorAt:put: - for future compatibility. |
2592 Use #colorAt:put: - for future compatibility. |
2593 |
2593 |
2594 set the pixel at x/y to aColor. |
2594 set the pixel at x/y to aColor. |
2598 (i.e. if the receiver is a palette image, the color must be present in there). |
2598 (i.e. if the receiver is a palette image, the color must be present in there). |
2599 You should not use this method for image-processing, it is very slow ... |
2599 You should not use this method for image-processing, it is very slow ... |
2600 (it is meant to access individual pixels - for example, in a bitmap editor)" |
2600 (it is meant to access individual pixels - for example, in a bitmap editor)" |
2601 |
2601 |
2602 aColor isInteger ifTrue:[ |
2602 aColor isInteger ifTrue:[ |
2603 'Image [warning]: the Image>>atX:y:put: will change semantics soon; use #colorAtX:y:put:' infoPrintCR. |
2603 'Image [warning]: the Image>>atX:y:put: will change semantics soon; use #colorAtX:y:put:' infoPrintCR. |
2604 ^ self pixelAtX:x y:y put:aColor |
2604 ^ self pixelAtX:x y:y put:aColor |
2605 ]. |
2605 ]. |
2606 ^ self colorAtX:x y:y put:aColor |
2606 ^ self colorAtX:x y:y put:aColor |
2607 |
2607 |
2608 "Modified: 21.6.1997 / 13:10:44 / cg" |
2608 "Modified: 21.6.1997 / 13:10:44 / cg" |
2609 ! |
2609 ! |
2627 ! |
2627 ! |
2628 |
2628 |
2629 bits |
2629 bits |
2630 "return the raw image data; depending on the photometric, |
2630 "return the raw image data; depending on the photometric, |
2631 this has to be interpreted as monochrome, greyscale, |
2631 this has to be interpreted as monochrome, greyscale, |
2632 palette or rgb data. |
2632 palette or rgb data. |
2633 It is also packed to be dense, so a 4 bitPerSample palette image |
2633 It is also packed to be dense, so a 4 bitPerSample palette image |
2634 will store 2 pixels per byte, whereas a 2-bitPerPixel image will store |
2634 will store 2 pixels per byte, whereas a 2-bitPerPixel image will store |
2635 4 pixels per byte." |
2635 4 pixels per byte." |
2636 |
2636 |
2637 ^ bytes |
2637 ^ bytes |
2638 ! |
2638 ! |
2782 Pixels start at 0/0 for upper left pixel, and end at |
2782 Pixels start at 0/0 for upper left pixel, and end at |
2783 width-1@height-1 for lower right pixel. |
2783 width-1@height-1 for lower right pixel. |
2784 The returned numbers interpretation depends on the photometric |
2784 The returned numbers interpretation depends on the photometric |
2785 and the colormap. (see also Image>>at: and Image>>atX:y:) |
2785 and the colormap. (see also Image>>at: and Image>>atX:y:) |
2786 You should not use this method for image-processing of |
2786 You should not use this method for image-processing of |
2787 big images, its very slow ... |
2787 big images, its very slow ... |
2788 (it is meant to access individual pixels - for example, in a bitmap editor)" |
2788 (it is meant to access individual pixels - for example, in a bitmap editor)" |
2789 |
2789 |
2790 ^ self subclassResponsibility |
2790 ^ self subclassResponsibility |
2791 |
2791 |
2792 "Created: 24.4.1997 / 16:06:56 / cg" |
2792 "Created: 24.4.1997 / 16:06:56 / cg" |
2908 |
2908 |
2909 "Modified: 24.4.1997 / 17:05:57 / cg" |
2909 "Modified: 24.4.1997 / 17:05:57 / cg" |
2910 ! |
2910 ! |
2911 |
2911 |
2912 valueAt:aPoint |
2912 valueAt:aPoint |
2913 "WARNING: for now, this returns a pixels value |
2913 "WARNING: for now, this returns a pixels value |
2914 (backward compatibility with ST/X) |
2914 (backward compatibility with ST/X) |
2915 In the future, this will return a color (ST-80 compatibility) |
2915 In the future, this will return a color (ST-80 compatibility) |
2916 Use #pixelAt: - for future compatibility. |
2916 Use #pixelAt: - for future compatibility. |
2917 |
2917 |
2918 Retrieve the pixelValue at aPoint; return an integer number. |
2918 Retrieve the pixelValue at aPoint; return an integer number. |
2929 |
2929 |
2930 "Modified: 21.6.1997 / 13:11:19 / cg" |
2930 "Modified: 21.6.1997 / 13:11:19 / cg" |
2931 ! |
2931 ! |
2932 |
2932 |
2933 valueAtX:x y:y |
2933 valueAtX:x y:y |
2934 "WARNING: for now, this returns a pixels value |
2934 "WARNING: for now, this returns a pixels value |
2935 (backward compatibility with ST/X) |
2935 (backward compatibility with ST/X) |
2936 In the future, this will return a color (ST-80 compatibility) |
2936 In the future, this will return a color (ST-80 compatibility) |
2937 Use #pixelAt: - for future compatibility. |
2937 Use #pixelAt: - for future compatibility. |
2938 |
2938 |
2939 Retrieve the pixelValue at aPoint; return an integer number. |
2939 Retrieve the pixelValue at aPoint; return an integer number. |
2940 Pixels start at 0/0 for upper left pixel, and end at |
2940 Pixels start at 0/0 for upper left pixel, and end at |
2941 width-1@height-1 for lower right pixel. |
2941 width-1@height-1 for lower right pixel. |
2942 The returned numbers interpretation depends on the photometric |
2942 The returned numbers interpretation depends on the photometric |
2943 and the colormap. (see also Image>>at: and Image>>atX:y:) |
2943 and the colormap. (see also Image>>at: and Image>>atX:y:) |
2944 You should not use this method for image-processing of |
2944 You should not use this method for image-processing of |
2945 big images, its very slow ... |
2945 big images, its very slow ... |
2946 (it is meant to access individual pixels - for example, in a bitmap editor)" |
2946 (it is meant to access individual pixels - for example, in a bitmap editor)" |
2947 |
2947 |
2948 'Image [warning]: the Image>>valueAtX:y: will change semantics soon; use #pixelAtX:y' infoPrintCR. |
2948 'Image [warning]: the Image>>valueAtX:y: will change semantics soon; use #pixelAtX:y' infoPrintCR. |
2949 ^ self pixelAtX:x y:y |
2949 ^ self pixelAtX:x y:y |
2950 |
2950 |
2965 |
2965 |
2966 "Modified: 23.4.1996 / 11:08:28 / cg" |
2966 "Modified: 23.4.1996 / 11:08:28 / cg" |
2967 ! |
2967 ! |
2968 |
2968 |
2969 bitsPerSample:aCollection |
2969 bitsPerSample:aCollection |
2970 "set the number of bits per sample. |
2970 "set the number of bits per sample. |
2971 |
2971 |
2972 This interface is only to be used when initializing |
2972 This interface is only to be used when initializing |
2973 instances or by image readers. Calling for a change of an |
2973 instances or by image readers. Calling for a change of an |
2974 existing image may confuse later pixel interpretation." |
2974 existing image may confuse later pixel interpretation." |
2975 |
2975 |
2986 existing image may confuse later pixel interpretation." |
2986 existing image may confuse later pixel interpretation." |
2987 |
2987 |
2988 depth := self depth. |
2988 depth := self depth. |
2989 bitsPerPixel := d. |
2989 bitsPerPixel := d. |
2990 d == 24 ifTrue:[ |
2990 d == 24 ifTrue:[ |
2991 samplesPerPixel := 3. |
2991 samplesPerPixel := 3. |
2992 bitsPerSample := #[8 8 8] |
2992 bitsPerSample := #[8 8 8] |
2993 ] ifFalse:[ |
2993 ] ifFalse:[ |
2994 samplesPerPixel := 1. |
2994 samplesPerPixel := 1. |
2995 bitsPerSample := ByteArray with:d |
2995 bitsPerSample := ByteArray with:d |
2996 ] |
2996 ] |
2997 |
2997 |
2998 "Modified: 20.2.1997 / 14:39:10 / cg" |
2998 "Modified: 20.2.1997 / 14:39:10 / cg" |
2999 ! |
2999 ! |
3000 |
3000 |
3024 ! |
3024 ! |
3025 |
3025 |
3026 photometric:aSymbol |
3026 photometric:aSymbol |
3027 "set the photometric interpretation of the pixel values. |
3027 "set the photometric interpretation of the pixel values. |
3028 The argument, aSymbol is one of: |
3028 The argument, aSymbol is one of: |
3029 #blackIs0, #whiteIs0, #palette, #rgb |
3029 #blackIs0, #whiteIs0, #palette, #rgb |
3030 See TIFF documentation, from which the photometric concept is borrowed. |
3030 See TIFF documentation, from which the photometric concept is borrowed. |
3031 |
3031 |
3032 This interface is only to be used when initializing |
3032 This interface is only to be used when initializing |
3033 instances or by image readers. Calling for a change of an |
3033 instances or by image readers. Calling for a change of an |
3034 existing image may confuse later pixel interpretation." |
3034 existing image may confuse later pixel interpretation." |
3035 |
3035 |
3036 |b| |
3036 |b| |
3037 |
3037 |
3038 photometric := aSymbol. |
3038 photometric := aSymbol. |
3039 bitsPerSample isNil ifTrue:[ |
3039 bitsPerSample isNil ifTrue:[ |
3040 photometric == #rgb ifTrue:[ |
3040 photometric == #rgb ifTrue:[ |
3041 b := self class imageDepth // 3. |
3041 b := self class imageDepth // 3. |
3042 bitsPerSample := ByteArray with:b with:b with:b |
3042 bitsPerSample := ByteArray with:b with:b with:b |
3043 ] ifFalse:[ |
3043 ] ifFalse:[ |
3044 bitsPerSample := ByteArray with:(self class imageDepth) |
3044 bitsPerSample := ByteArray with:(self class imageDepth) |
3045 ]. |
3045 ]. |
3046 ]. |
3046 ]. |
3047 samplesPerPixel isNil ifTrue:[ |
3047 samplesPerPixel isNil ifTrue:[ |
3048 photometric == #rgb ifTrue:[ |
3048 photometric == #rgb ifTrue:[ |
3049 samplesPerPixel := 3 |
3049 samplesPerPixel := 3 |
3050 ] ifFalse:[ |
3050 ] ifFalse:[ |
3051 samplesPerPixel := 1 |
3051 samplesPerPixel := 1 |
3052 ] |
3052 ] |
3053 ]. |
3053 ]. |
3054 |
3054 |
3055 "Modified: 10.6.1996 / 18:21:29 / cg" |
3055 "Modified: 10.6.1996 / 18:21:29 / cg" |
3056 ! |
3056 ! |
3057 |
3057 |
3077 width := aNumber |
3077 width := aNumber |
3078 |
3078 |
3079 "Modified: 23.4.1996 / 11:08:48 / cg" |
3079 "Modified: 23.4.1996 / 11:08:48 / cg" |
3080 ! |
3080 ! |
3081 |
3081 |
3082 width:w height:h |
3082 width:w height:h |
3083 "set the width and height of the image. |
3083 "set the width and height of the image. |
3084 |
3084 |
3085 This interface is only to be used when initializing |
3085 This interface is only to be used when initializing |
3086 instances or by image readers. Calling for a change of an |
3086 instances or by image readers. Calling for a change of an |
3087 existing image may confuse later pixel interpretation." |
3087 existing image may confuse later pixel interpretation." |
3146 This interface is only to be used when initializing |
3146 This interface is only to be used when initializing |
3147 instances or by image readers. Calling for a change of an |
3147 instances or by image readers. Calling for a change of an |
3148 existing image may confuse later pixel interpretation." |
3148 existing image may confuse later pixel interpretation." |
3149 |
3149 |
3150 ^ self |
3150 ^ self |
3151 width:w |
3151 width:w |
3152 height:h |
3152 height:h |
3153 photometric:p |
3153 photometric:p |
3154 samplesPerPixel:spp |
3154 samplesPerPixel:spp |
3155 bitsPerSample:bps |
3155 bitsPerSample:bps |
3156 colorMap:cm |
3156 colorMap:cm |
3157 bits:pixels |
3157 bits:pixels |
3158 mask:nil |
3158 mask:nil |
3159 |
3159 |
3160 "Modified: 20.6.1996 / 17:10:24 / cg" |
3160 "Modified: 20.6.1996 / 17:10:24 / cg" |
3161 ! |
3161 ! |
3162 |
3162 |
3269 |
3269 |
3270 " |
3270 " |
3271 |i| |
3271 |i| |
3272 |
3272 |
3273 i := Depth4Image |
3273 i := Depth4Image |
3274 width:4 |
3274 width:4 |
3275 height:4 |
3275 height:4 |
3276 fromArray:#[ |
3276 fromArray:#[ |
3277 16r01 16r23 |
3277 16r01 16r23 |
3278 16r45 16r67 |
3278 16r45 16r67 |
3279 16r89 16rab |
3279 16r89 16rab |
3280 16rcd 16ref |
3280 16rcd 16ref |
3281 ]. |
3281 ]. |
3282 i := i magnifiedBy:30. |
3282 i := i magnifiedBy:30. |
3283 i inspect. |
3283 i inspect. |
3284 i asFloydSteinbergDitheredMonochromeImage inspect. |
3284 i asFloydSteinbergDitheredMonochromeImage inspect. |
3285 i asBurkesDitheredMonochromeImage inspect. |
3285 i asBurkesDitheredMonochromeImage inspect. |
3286 i asOrderedDitheredMonochromeImage inspect. |
3286 i asOrderedDitheredMonochromeImage inspect. |
3313 |
3313 |
3314 asErrorDitheredMonochromeImage |
3314 asErrorDitheredMonochromeImage |
3315 "return an error-diffusion dithered monochrome image from the receiver image." |
3315 "return an error-diffusion dithered monochrome image from the receiver image." |
3316 |
3316 |
3317 DitherAlgorithm == #burkes ifTrue:[ |
3317 DitherAlgorithm == #burkes ifTrue:[ |
3318 ^ self asBurkesDitheredMonochromeImage |
3318 ^ self asBurkesDitheredMonochromeImage |
3319 ]. |
3319 ]. |
3320 DitherAlgorithm == #stevensonArce ifTrue:[ |
3320 DitherAlgorithm == #stevensonArce ifTrue:[ |
3321 ^ self asStevensonArceDitheredMonochromeImage |
3321 ^ self asStevensonArceDitheredMonochromeImage |
3322 ]. |
3322 ]. |
3323 ^ self asFloydSteinbergDitheredMonochromeImage |
3323 ^ self asFloydSteinbergDitheredMonochromeImage |
3324 |
3324 |
3325 " |
3325 " |
3326 |i| |
3326 |i| |
3342 |
3342 |
3343 " |
3343 " |
3344 |i| |
3344 |i| |
3345 |
3345 |
3346 i := Depth4Image |
3346 i := Depth4Image |
3347 width:4 |
3347 width:4 |
3348 height:4 |
3348 height:4 |
3349 fromArray:#[ |
3349 fromArray:#[ |
3350 16r01 16r23 |
3350 16r01 16r23 |
3351 16r45 16r67 |
3351 16r45 16r67 |
3352 16r89 16rab |
3352 16r89 16rab |
3353 16rcd 16ref |
3353 16rcd 16ref |
3354 ]. |
3354 ]. |
3355 i := i magnifiedBy:30. |
3355 i := i magnifiedBy:30. |
3356 i inspect. |
3356 i inspect. |
3357 i asErrorDitheredMonochromeImage inspect. |
3357 i asErrorDitheredMonochromeImage inspect. |
3358 i asOrderedDitheredMonochromeImage inspect. |
3358 i asOrderedDitheredMonochromeImage inspect. |
3359 " |
3359 " |
3360 |
3360 |
3361 "Modified: 10.6.1996 / 14:22:30 / cg" |
3361 "Modified: 10.6.1996 / 14:22:30 / cg" |
3362 ! |
3362 ! |
3363 |
3363 |
3364 asFloydSteinbergDitheredDepth8FormOn:aDevice colors:fixColors |
3364 asFloydSteinbergDitheredDepth8FormOn:aDevice colors:fixColors |
3365 "return a floyd-steinberg dithered pseudoForm from the picture. |
3365 "return a floyd-steinberg dithered pseudoForm from the picture. |
3366 Use the colors in the fixColors array. |
3366 Use the colors in the fixColors array. |
3367 By passing the ditherColors as extra array, this method can |
3367 By passing the ditherColors as extra array, this method can |
3368 also be used to dither an 8bit image into a smaller number of colors, |
3368 also be used to dither an 8bit image into a smaller number of colors, |
3369 for example to create dithered Depth4Images from Depth8Images." |
3369 for example to create dithered Depth4Images from Depth8Images." |
3370 |
3370 |
3371 |pseudoBits f deviceDepth map| |
3371 |pseudoBits f deviceDepth map| |
3372 |
3372 |
3373 deviceDepth := aDevice depth. |
3373 deviceDepth := aDevice depth. |
3374 deviceDepth == 8 ifFalse:[ |
3374 deviceDepth == 8 ifFalse:[ |
3375 (aDevice supportedImageFormatForDepth:8) isNil ifTrue:[ |
3375 (aDevice supportedImageFormatForDepth:8) isNil ifTrue:[ |
3376 ^ nil. |
3376 ^ nil. |
3377 ] |
3377 ] |
3378 ]. |
3378 ]. |
3379 |
3379 |
3380 pseudoBits := self floydSteinbergDitheredDepth8BitsColors:fixColors. |
3380 pseudoBits := self floydSteinbergDitheredDepth8BitsColors:fixColors. |
3381 pseudoBits isNil ifTrue:[^ nil]. |
3381 pseudoBits isNil ifTrue:[^ nil]. |
3382 |
3382 |
3387 "/ have to create a funny colorMap, where |
3387 "/ have to create a funny colorMap, where |
3388 "/ color at:index == color colorId:index |
3388 "/ color at:index == color colorId:index |
3389 "/ |
3389 "/ |
3390 map := Array new:256. |
3390 map := Array new:256. |
3391 fixColors do:[:clr | |
3391 fixColors do:[:clr | |
3392 map at:clr colorId + 1 put:clr |
3392 map at:clr colorId + 1 put:clr |
3393 ]. |
3393 ]. |
3394 f colorMap:map. |
3394 f colorMap:map. |
3395 f initGC. |
3395 f initGC. |
3396 f bits:pseudoBits. |
3396 f bits:pseudoBits. |
3397 aDevice |
3397 aDevice |
3398 drawBits:pseudoBits |
3398 drawBits:pseudoBits |
3399 bitsPerPixel:8 |
3399 bitsPerPixel:8 |
3400 depth:deviceDepth |
3400 depth:deviceDepth |
3401 padding:8 |
3401 padding:8 |
3402 width:width height:height |
3402 width:width height:height |
3403 x:0 y:0 |
3403 x:0 y:0 |
3404 into:(f id) x:0 y:0 |
3404 into:(f id) x:0 y:0 |
3405 width:width height:height |
3405 width:width height:height |
3406 with:(f gcId). |
3406 with:(f gcId). |
3407 ^ f |
3407 ^ f |
3408 |
3408 |
3409 " |
3409 " |
3410 example: |
3410 example: |
3411 color reduction from Depth8 to Depth4 (dithering) can be done by: |
3411 color reduction from Depth8 to Depth4 (dithering) can be done by: |
3412 |
3412 |
3413 |img8 reducedImg8 img4 map form| |
3413 |img8 reducedImg8 img4 map form| |
3414 |
3414 |
3415 map := #( |
3415 map := #( |
3416 (0 0 0) |
3416 (0 0 0) |
3417 (0 0 100) |
3417 (0 0 100) |
3418 (0 50 0) |
3418 (0 50 0) |
3419 (0 50 100) |
3419 (0 50 100) |
3420 (0 100 0) |
3420 (0 100 0) |
3421 (0 100 100) |
3421 (0 100 100) |
3422 (100 0 0) |
3422 (100 0 0) |
3423 (100 0 100) |
3423 (100 0 100) |
3424 (100 50 0) |
3424 (100 50 0) |
3425 (100 50 100) |
3425 (100 50 100) |
3426 (100 100 0) |
3426 (100 100 0) |
3427 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
3427 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
3428 green:(rgb at:2) |
3428 green:(rgb at:2) |
3429 blue:(rgb at:3)) onDevice:Display]. |
3429 blue:(rgb at:3)) onDevice:Display]. |
3430 |
3430 |
3431 img8 := Image fromFile:'goodies/bitmaps/bf.im8'. |
3431 img8 := Image fromFile:'goodies/bitmaps/bf.im8'. |
3432 form := img8 paletteImageAsDitheredPseudoFormOn:Display |
3432 form := img8 paletteImageAsDitheredPseudoFormOn:Display |
3433 colors:map |
3433 colors:map |
3434 nRed:2 |
3434 nRed:2 |
3435 nGreen:3 |
3435 nGreen:3 |
3436 nBlue:2. |
3436 nBlue:2. |
3437 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
3437 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
3438 img4 := Depth4Image fromImage:img8. |
3438 img4 := Depth4Image fromImage:img8. |
3439 " |
3439 " |
3440 |
3440 |
3441 "Modified: 14.6.1996 / 16:52:34 / cg" |
3441 "Modified: 14.6.1996 / 16:52:34 / cg" |
3442 "Created: 23.6.1997 / 15:25:37 / cg" |
3442 "Created: 23.6.1997 / 15:25:37 / cg" |
3443 ! |
3443 ! |
3444 |
3444 |
3445 asFloydSteinbergDitheredDepth8FormOn:aDevice colors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
3445 asFloydSteinbergDitheredDepth8FormOn:aDevice colors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
3446 "return a floyd-steinberg dithered pseudoForm from the palette picture. |
3446 "return a floyd-steinberg dithered pseudoForm from the palette picture. |
3447 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
3447 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
3448 colors assigned to aDevice, such as the preallocated colors of the |
3448 colors assigned to aDevice, such as the preallocated colors of the |
3449 Color class. |
3449 Color class. |
3450 By passing the ditherColors as extra array, this method can |
3450 By passing the ditherColors as extra array, this method can |
3451 also be used to dither an 8bit image into a smaller number of colors, |
3451 also be used to dither an 8bit image into a smaller number of colors, |
3452 for example to create dithered Depth4Images from Depth8Images." |
3452 for example to create dithered Depth4Images from Depth8Images." |
3453 |
3453 |
3454 |pseudoBits f deviceDepth map| |
3454 |pseudoBits f deviceDepth map| |
3455 |
3455 |
3456 deviceDepth := aDevice depth. |
3456 deviceDepth := aDevice depth. |
3457 deviceDepth == 8 ifFalse:[ |
3457 deviceDepth == 8 ifFalse:[ |
3458 (aDevice supportedImageFormatForDepth:8) isNil ifTrue:[ |
3458 (aDevice supportedImageFormatForDepth:8) isNil ifTrue:[ |
3459 ^ nil |
3459 ^ nil |
3460 ] |
3460 ] |
3461 ]. |
3461 ]. |
3462 |
3462 |
3463 pseudoBits := self floydSteinbergDitheredDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue. |
3463 pseudoBits := self floydSteinbergDitheredDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue. |
3464 pseudoBits isNil ifTrue:[^ nil]. |
3464 pseudoBits isNil ifTrue:[^ nil]. |
3465 |
3465 |
3470 "/ have to create a funny colorMap, where |
3470 "/ have to create a funny colorMap, where |
3471 "/ color at:index == color colorId:index |
3471 "/ color at:index == color colorId:index |
3472 "/ |
3472 "/ |
3473 map := Array new:256. |
3473 map := Array new:256. |
3474 fixColors do:[:clr | |
3474 fixColors do:[:clr | |
3475 map at:clr colorId + 1 put:clr |
3475 map at:clr colorId + 1 put:clr |
3476 ]. |
3476 ]. |
3477 f colorMap:map. |
3477 f colorMap:map. |
3478 f initGC. |
3478 f initGC. |
3479 f bits:pseudoBits. |
3479 f bits:pseudoBits. |
3480 aDevice |
3480 aDevice |
3481 drawBits:pseudoBits |
3481 drawBits:pseudoBits |
3482 bitsPerPixel:8 |
3482 bitsPerPixel:8 |
3483 depth:deviceDepth |
3483 depth:deviceDepth |
3484 padding:8 |
3484 padding:8 |
3485 width:width height:height |
3485 width:width height:height |
3486 x:0 y:0 |
3486 x:0 y:0 |
3487 into:(f id) x:0 y:0 |
3487 into:(f id) x:0 y:0 |
3488 width:width height:height |
3488 width:width height:height |
3489 with:(f gcId). |
3489 with:(f gcId). |
3490 ^ f |
3490 ^ f |
3491 |
3491 |
3492 " |
3492 " |
3493 example: |
3493 example: |
3494 color reduction from Depth8 to Depth4 (dithering) can be done by: |
3494 color reduction from Depth8 to Depth4 (dithering) can be done by: |
3495 |
3495 |
3496 |img8 reducedImg8 img4 map form| |
3496 |img8 reducedImg8 img4 map form| |
3497 |
3497 |
3498 map := #( |
3498 map := #( |
3499 (0 0 0) |
3499 (0 0 0) |
3500 (0 0 100) |
3500 (0 0 100) |
3501 (0 50 0) |
3501 (0 50 0) |
3502 (0 50 100) |
3502 (0 50 100) |
3503 (0 100 0) |
3503 (0 100 0) |
3504 (0 100 100) |
3504 (0 100 100) |
3505 (100 0 0) |
3505 (100 0 0) |
3506 (100 0 100) |
3506 (100 0 100) |
3507 (100 50 0) |
3507 (100 50 0) |
3508 (100 50 100) |
3508 (100 50 100) |
3509 (100 100 0) |
3509 (100 100 0) |
3510 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
3510 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
3511 green:(rgb at:2) |
3511 green:(rgb at:2) |
3512 blue:(rgb at:3)) onDevice:Display]. |
3512 blue:(rgb at:3)) onDevice:Display]. |
3513 |
3513 |
3514 img8 := Image fromFile:'goodies/bitmaps/bf.im8'. |
3514 img8 := Image fromFile:'goodies/bitmaps/bf.im8'. |
3515 form := img8 paletteImageAsDitheredPseudoFormOn:Display |
3515 form := img8 paletteImageAsDitheredPseudoFormOn:Display |
3516 colors:map |
3516 colors:map |
3517 nRed:2 |
3517 nRed:2 |
3518 nGreen:3 |
3518 nGreen:3 |
3519 nBlue:2. |
3519 nBlue:2. |
3520 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
3520 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
3521 img4 := Depth4Image fromImage:img8. |
3521 img4 := Depth4Image fromImage:img8. |
3522 " |
3522 " |
3523 |
3523 |
3524 "Modified: 14.6.1996 / 16:52:34 / cg" |
3524 "Modified: 14.6.1996 / 16:52:34 / cg" |
3585 |
3585 |
3586 " |
3586 " |
3587 |i| |
3587 |i| |
3588 |
3588 |
3589 i := Depth24Image width:4 height:1 |
3589 i := Depth24Image width:4 height:1 |
3590 fromArray:#[ |
3590 fromArray:#[ |
3591 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
3591 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
3592 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
3592 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
3593 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
3593 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 |
3594 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00]. |
3594 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00 16rFF 16r00 16r00]. |
3595 i := i magnifiedBy:4@1. |
3595 i := i magnifiedBy:4@1. |
3602 |
3602 |
3603 " |
3603 " |
3604 |i| |
3604 |i| |
3605 |
3605 |
3606 i := Depth24Image width:4 height:6 |
3606 i := Depth24Image width:4 height:6 |
3607 fromArray:#[ |
3607 fromArray:#[ |
3608 16r00 16r00 16r00 16r00 16r00 16r80 16r00 16r00 16rff 16r00 16r80 16r00 |
3608 16r00 16r00 16r00 16r00 16r00 16r80 16r00 16r00 16rff 16r00 16r80 16r00 |
3609 16r00 16r80 16r80 16r00 16rFF 16r00 16r00 16rFF 16r80 16r00 16rFF 16rFF |
3609 16r00 16r80 16r80 16r00 16rFF 16r00 16r00 16rFF 16r80 16r00 16rFF 16rFF |
3610 16r80 16r00 16r00 16r80 16r00 16r80 16r80 16r00 16rff 16r80 16r80 16r00 |
3610 16r80 16r00 16r00 16r80 16r00 16r80 16r80 16r00 16rff 16r80 16r80 16r00 |
3611 16r80 16r80 16r80 16r80 16rFF 16r00 16r80 16rFF 16r80 16r80 16rFF 16rFF |
3611 16r80 16r80 16r80 16r80 16rFF 16r00 16r80 16rFF 16r80 16r80 16rFF 16rFF |
3612 16rFF 16r00 16r00 16rFF 16r00 16r80 16rFF 16r00 16rff 16rFF 16r80 16r00 |
3612 16rFF 16r00 16r00 16rFF 16r00 16r80 16rFF 16r00 16rff 16rFF 16r80 16r00 |
3640 |
3640 |
3641 " |
3641 " |
3642 |i| |
3642 |i| |
3643 |
3643 |
3644 i := Depth4Image |
3644 i := Depth4Image |
3645 width:4 |
3645 width:4 |
3646 height:4 |
3646 height:4 |
3647 fromArray:#[ |
3647 fromArray:#[ |
3648 16r01 16r23 |
3648 16r01 16r23 |
3649 16r45 16r67 |
3649 16r45 16r67 |
3650 16r89 16rab |
3650 16r89 16rab |
3651 16rcd 16ref |
3651 16rcd 16ref |
3652 ]. |
3652 ]. |
3653 i := i magnifiedBy:30. |
3653 i := i magnifiedBy:30. |
3654 i inspect. |
3654 i inspect. |
3655 (i asFloydSteinbergDitheredGrayImageDepth:1) inspect. |
3655 (i asFloydSteinbergDitheredGrayImageDepth:1) inspect. |
3656 (i asFloydSteinbergDitheredGrayImageDepth:2) inspect. |
3656 (i asFloydSteinbergDitheredGrayImageDepth:2) inspect. |
3727 |
3727 |
3728 " |
3728 " |
3729 |i| |
3729 |i| |
3730 |
3730 |
3731 i := Depth4Image |
3731 i := Depth4Image |
3732 width:4 |
3732 width:4 |
3733 height:4 |
3733 height:4 |
3734 fromArray:#[ |
3734 fromArray:#[ |
3735 16r01 16r23 |
3735 16r01 16r23 |
3736 16r45 16r67 |
3736 16r45 16r67 |
3737 16r89 16rab |
3737 16r89 16rab |
3738 16rcd 16ref |
3738 16rcd 16ref |
3739 ]. |
3739 ]. |
3740 i := i magnifiedBy:30. |
3740 i := i magnifiedBy:30. |
3741 i inspect. |
3741 i inspect. |
3742 i asFloydSteinbergDitheredMonochromeImage inspect. |
3742 i asFloydSteinbergDitheredMonochromeImage inspect. |
3743 i asBurkesDitheredMonochromeImage inspect. |
3743 i asBurkesDitheredMonochromeImage inspect. |
3754 |
3754 |
3755 |pseudoBits pseudoBits8 f has8BitImage deviceDepth map d| |
3755 |pseudoBits pseudoBits8 f has8BitImage deviceDepth map d| |
3756 |
3756 |
3757 deviceDepth := aDevice depth. |
3757 deviceDepth := aDevice depth. |
3758 has8BitImage := (deviceDepth == 8) |
3758 has8BitImage := (deviceDepth == 8) |
3759 or:[ (aDevice supportedImageFormatForDepth:8) notNil ]. |
3759 or:[ (aDevice supportedImageFormatForDepth:8) notNil ]. |
3760 |
3760 |
3761 has8BitImage ifFalse:[ |
3761 has8BitImage ifFalse:[ |
3762 deviceDepth == 4 ifFalse:[^ nil]. |
3762 deviceDepth == 4 ifFalse:[^ nil]. |
3763 |
3763 |
3764 pseudoBits8 := self nfloydSteinbergDitheredDepth8BitsColors:colors. |
3764 pseudoBits8 := self nfloydSteinbergDitheredDepth8BitsColors:colors. |
3765 pseudoBits8 isNil ifTrue:[^ nil]. |
3765 pseudoBits8 isNil ifTrue:[^ nil]. |
3766 "/ convert to devices depth |
3766 "/ convert to devices depth |
3767 |
3767 |
3768 pseudoBits := ByteArray new:(width*4+7//8 * height). |
3768 pseudoBits := ByteArray new:(width*4+7//8 * height). |
3769 pseudoBits8 compressPixels:4 width:width height:height into:pseudoBits mapping:nil. |
3769 pseudoBits8 compressPixels:4 width:width height:height into:pseudoBits mapping:nil. |
3770 d := 4. |
3770 d := 4. |
3771 ] ifTrue:[ |
3771 ] ifTrue:[ |
3772 pseudoBits := self nfloydSteinbergDitheredDepth8BitsColors:colors. |
3772 pseudoBits := self nfloydSteinbergDitheredDepth8BitsColors:colors. |
3773 pseudoBits isNil ifTrue:[^ nil]. |
3773 pseudoBits isNil ifTrue:[^ nil]. |
3774 d := 8. |
3774 d := 8. |
3775 ]. |
3775 ]. |
3776 |
3776 |
3777 f := Form width:width height:height depth:deviceDepth on:aDevice. |
3777 f := Form width:width height:height depth:deviceDepth on:aDevice. |
3778 f isNil ifTrue:[^ nil]. |
3778 f isNil ifTrue:[^ nil]. |
3779 |
3779 |
3781 "/ have to create a funny colorMap, where |
3781 "/ have to create a funny colorMap, where |
3782 "/ color at:index == color colorId:index |
3782 "/ color at:index == color colorId:index |
3783 "/ |
3783 "/ |
3784 map := Array new:256 withAll:0. |
3784 map := Array new:256 withAll:0. |
3785 colors do:[:clr | |
3785 colors do:[:clr | |
3786 clr notNil ifTrue:[ |
3786 clr notNil ifTrue:[ |
3787 map at:clr colorId + 1 put:clr |
3787 map at:clr colorId + 1 put:clr |
3788 ] |
3788 ] |
3789 ]. |
3789 ]. |
3790 f colorMap:map. |
3790 f colorMap:map. |
3791 f initGC. |
3791 f initGC. |
3792 f bits:pseudoBits. |
3792 f bits:pseudoBits. |
3793 aDevice |
3793 aDevice |
3794 drawBits:pseudoBits |
3794 drawBits:pseudoBits |
3795 bitsPerPixel:d |
3795 bitsPerPixel:d |
3796 depth:deviceDepth |
3796 depth:deviceDepth |
3797 padding:8 |
3797 padding:8 |
3798 width:width height:height |
3798 width:width height:height |
3799 x:0 y:0 |
3799 x:0 y:0 |
3800 into:(f id) x:0 y:0 |
3800 into:(f id) x:0 y:0 |
3801 width:width height:height |
3801 width:width height:height |
3802 with:(f gcId). |
3802 with:(f gcId). |
3803 ^ f |
3803 ^ f |
3804 |
3804 |
3805 " |
3805 " |
3806 |i| |
3806 |i| |
3807 |
3807 |
3826 |form visual| |
3826 |form visual| |
3827 |
3827 |
3828 ((aDevice == device) and:[deviceForm notNil]) ifTrue:[^ deviceForm]. |
3828 ((aDevice == device) and:[deviceForm notNil]) ifTrue:[^ deviceForm]. |
3829 |
3829 |
3830 mask notNil ifTrue:[ |
3830 mask notNil ifTrue:[ |
3831 mask := mask onDevice:aDevice |
3831 mask := mask onDevice:aDevice |
3832 ]. |
3832 ]. |
3833 |
3833 |
3834 (aDevice depth == 1 |
3834 (aDevice depth == 1 |
3835 or:[aDevice hasGrayscales not]) ifTrue:[ |
3835 or:[aDevice hasGrayscales not]) ifTrue:[ |
3836 form := self asMonochromeFormOn:aDevice. |
3836 form := self asMonochromeFormOn:aDevice. |
3837 ] ifFalse:[ |
3837 ] ifFalse:[ |
3838 ((visual := aDevice visualType) == #StaticGray) ifTrue:[ |
3838 ((visual := aDevice visualType) == #StaticGray) ifTrue:[ |
3839 form := self asGrayFormOn:aDevice. |
3839 form := self asGrayFormOn:aDevice. |
3840 ] ifFalse:[ |
3840 ] ifFalse:[ |
3841 (visual == #PseudoColor |
3841 (visual == #PseudoColor |
3842 or:[visual == #StaticColor]) ifTrue:[ |
3842 or:[visual == #StaticColor]) ifTrue:[ |
3843 form := self asPseudoFormQuickOn:aDevice. |
3843 form := self asPseudoFormQuickOn:aDevice. |
3844 ]. |
3844 ]. |
3845 ] |
3845 ] |
3846 ]. |
3846 ]. |
3847 |
3847 |
3848 form isNil ifTrue:[ |
3848 form isNil ifTrue:[ |
3849 (photometric == #palette) ifTrue:[ |
3849 (photometric == #palette) ifTrue:[ |
3850 form := self paletteImageAsFormOn:aDevice |
3850 form := self paletteImageAsFormOn:aDevice |
3851 ] ifFalse:[ |
3851 ] ifFalse:[ |
3852 (photometric == #rgb) ifTrue:[ |
3852 (photometric == #rgb) ifTrue:[ |
3853 form := self rgbImageAsFormOn:aDevice |
3853 form := self rgbImageAsFormOn:aDevice |
3854 ] ifFalse:[ |
3854 ] ifFalse:[ |
3855 (photometric == #cmy or:[photometric == #cmyk]) ifTrue:[ |
3855 (photometric == #cmy or:[photometric == #cmyk]) ifTrue:[ |
3856 form := self rgbImageAsFormOn:aDevice |
3856 form := self rgbImageAsFormOn:aDevice |
3857 ] ifFalse:[ |
3857 ] ifFalse:[ |
3858 form := self greyImageAsFormOn:aDevice |
3858 form := self greyImageAsFormOn:aDevice |
3859 ] |
3859 ] |
3860 ] |
3860 ] |
3861 ]. |
3861 ]. |
3862 ]. |
3862 ]. |
3863 |
3863 |
3864 (device isNil or:[aDevice == device]) ifTrue:[ |
3864 (device isNil or:[aDevice == device]) ifTrue:[ |
3865 "remember this form in the receiver ..." |
3865 "remember this form in the receiver ..." |
3866 |
3866 |
3867 form notNil ifTrue:[ |
3867 form notNil ifTrue:[ |
3868 form := form asImageForm. |
3868 form := form asImageForm. |
3869 deviceForm := form. |
3869 deviceForm := form. |
3870 maskedPixelsAre0 := nil. |
3870 maskedPixelsAre0 := nil. |
3871 device isNil ifTrue:[ |
3871 device isNil ifTrue:[ |
3872 device := aDevice. |
3872 device := aDevice. |
3873 Lobby register:self |
3873 Lobby register:self |
3874 ] ifFalse:[ |
3874 ] ifFalse:[ |
3875 Lobby registerChange:self |
3875 Lobby registerChange:self |
3876 ]. |
3876 ]. |
3877 " |
3877 " |
3878 can save space, by not keeping the images data-bits |
3878 can save space, by not keeping the images data-bits |
3879 twice (here and in the device form) |
3879 twice (here and in the device form) |
3880 " |
3880 " |
3881 form forgetBits |
3881 form forgetBits |
3882 ] |
3882 ] |
3883 ]. |
3883 ]. |
3884 |
3884 |
3885 ^ form |
3885 ^ form |
3886 |
3886 |
3887 " |
3887 " |
3939 |
3939 |
3940 asGrayImageDepth:depth |
3940 asGrayImageDepth:depth |
3941 "get a gray image from the receiver" |
3941 "get a gray image from the receiver" |
3942 |
3942 |
3943 (self colorMap notNil and:[depth == self depth]) ifTrue:[ |
3943 (self colorMap notNil and:[depth == self depth]) ifTrue:[ |
3944 ^ self copyWithColorMapProcessing:[:clr | Color brightness:(clr brightness)]. |
3944 ^ self copyWithColorMapProcessing:[:clr | Color brightness:(clr brightness)]. |
3945 ]. |
3945 ]. |
3946 ^ self asGrayImageDepth:depth dither:DitherAlgorithm. |
3946 ^ self asGrayImageDepth:depth dither:DitherAlgorithm. |
3947 |
3947 |
3948 " |
3948 " |
3949 |i| |
3949 |i| |
4005 |
4005 |
4006 |form| |
4006 |form| |
4007 |
4007 |
4008 ((aDevice == device) and:[monoDeviceForm notNil]) ifTrue:[^ monoDeviceForm]. |
4008 ((aDevice == device) and:[monoDeviceForm notNil]) ifTrue:[^ monoDeviceForm]. |
4009 self depth == 1 ifTrue:[ |
4009 self depth == 1 ifTrue:[ |
4010 ((aDevice == device) and:[deviceForm notNil]) ifTrue:[^ deviceForm]. |
4010 ((aDevice == device) and:[deviceForm notNil]) ifTrue:[^ deviceForm]. |
4011 ^ self asFormOn:aDevice |
4011 ^ self asFormOn:aDevice |
4012 ]. |
4012 ]. |
4013 |
4013 |
4014 form := self asMonochromeFormOn:aDevice dither:DitherAlgorithm. |
4014 form := self asMonochromeFormOn:aDevice dither:DitherAlgorithm. |
4015 |
4015 |
4016 (device isNil or:[aDevice == device]) ifTrue:[ |
4016 (device isNil or:[aDevice == device]) ifTrue:[ |
4017 "remember this form in the receiver ..." |
4017 "remember this form in the receiver ..." |
4018 |
4018 |
4019 form notNil ifTrue:[ |
4019 form notNil ifTrue:[ |
4020 form := form asImageForm. |
4020 form := form asImageForm. |
4021 monoDeviceForm := form. |
4021 monoDeviceForm := form. |
4022 device isNil ifTrue:[ |
4022 device isNil ifTrue:[ |
4023 device := aDevice. |
4023 device := aDevice. |
4024 Lobby register:self |
4024 Lobby register:self |
4025 ] ifFalse:[ |
4025 ] ifFalse:[ |
4026 Lobby registerChange:self |
4026 Lobby registerChange:self |
4027 ]. |
4027 ]. |
4028 " |
4028 " |
4029 can save space, by not keeping the images data-bits |
4029 can save space, by not keeping the images data-bits |
4030 twice (here and in the device form) |
4030 twice (here and in the device form) |
4031 " |
4031 " |
4032 form forgetBits |
4032 form forgetBits |
4033 ] |
4033 ] |
4034 ]. |
4034 ]. |
4035 |
4035 |
4036 ^ form |
4036 ^ form |
4037 |
4037 |
4038 " |
4038 " |
4076 ^ self makeDeviceMonochromeBitmapOn:aDevice fromArray:monoBits |
4076 ^ self makeDeviceMonochromeBitmapOn:aDevice fromArray:monoBits |
4077 |
4077 |
4078 "Modified: 10.6.1996 / 20:18:05 / cg" |
4078 "Modified: 10.6.1996 / 20:18:05 / cg" |
4079 ! |
4079 ! |
4080 |
4080 |
4081 asNearestPaintDepth8FormOn:aDevice colors:fixColors |
4081 asNearestPaintDepth8FormOn:aDevice colors:fixColors |
4082 "return a nearest paint pseudoForm from the palette picture. |
4082 "return a nearest paint pseudoForm from the palette picture. |
4083 Use the colors in the fixColors array. |
4083 Use the colors in the fixColors array. |
4084 By passing the ditherColors as extra array, this method can |
4084 By passing the ditherColors as extra array, this method can |
4085 also be used to dither an 8bit image into a smaller number of colors, |
4085 also be used to dither an 8bit image into a smaller number of colors, |
4086 for example to create dithered Depth4Images from Depth8Images." |
4086 for example to create dithered Depth4Images from Depth8Images." |
4087 |
4087 |
4088 ^ self asNearestPaintDepth8FormOn:aDevice colors:fixColors nRed:nil nGreen:nil nBlue:nil. |
4088 ^ self asNearestPaintDepth8FormOn:aDevice colors:fixColors nRed:nil nGreen:nil nBlue:nil. |
4089 |
4089 |
4090 " |
4090 " |
4091 example: |
4091 example: |
4092 color reduction from Depth8 to Depth4 can be done by: |
4092 color reduction from Depth8 to Depth4 can be done by: |
4093 |
4093 |
4094 |img8 reducedImg8 img4 map form| |
4094 |img8 reducedImg8 img4 map form| |
4095 |
4095 |
4096 map := #( |
4096 map := #( |
4097 (0 0 0) |
4097 (0 0 0) |
4098 (0 0 100) |
4098 (0 0 100) |
4099 (0 50 0) |
4099 (0 50 0) |
4100 (0 50 100) |
4100 (0 50 100) |
4101 (0 100 0) |
4101 (0 100 0) |
4102 (0 100 100) |
4102 (0 100 100) |
4103 (100 0 0) |
4103 (100 0 0) |
4104 (100 0 100) |
4104 (100 0 100) |
4105 (100 50 0) |
4105 (100 50 0) |
4106 (100 50 100) |
4106 (100 50 100) |
4107 (100 100 0) |
4107 (100 100 0) |
4108 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
4108 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
4109 green:(rgb at:2) |
4109 green:(rgb at:2) |
4110 blue:(rgb at:3)) onDevice:Display]. |
4110 blue:(rgb at:3)) onDevice:Display]. |
4111 |
4111 |
4112 img8 := Image fromFile:'goodies/bitmaps/claus.gif'. |
4112 img8 := Image fromFile:'goodies/bitmaps/claus.gif'. |
4113 form := img8 asNearestPaintDepth8FormOn:Display |
4113 form := img8 asNearestPaintDepth8FormOn:Display |
4114 colors:map |
4114 colors:map |
4115 nRed:2 |
4115 nRed:2 |
4116 nGreen:3 |
4116 nGreen:3 |
4117 nBlue:2. |
4117 nBlue:2. |
4118 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
4118 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
4119 img4 := Depth4Image fromImage:img8. |
4119 img4 := Depth4Image fromImage:img8. |
4120 " |
4120 " |
4121 |
4121 |
4122 "Modified: 17.6.1996 / 18:52:47 / cg" |
4122 "Modified: 17.6.1996 / 18:52:47 / cg" |
4123 "Created: 23.6.1997 / 15:26:09 / cg" |
4123 "Created: 23.6.1997 / 15:26:09 / cg" |
4124 ! |
4124 ! |
4125 |
4125 |
4126 asNearestPaintDepth8FormOn:aDevice colors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
4126 asNearestPaintDepth8FormOn:aDevice colors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
4127 "return a nearest paint pseudoForm from the palette picture. |
4127 "return a nearest paint pseudoForm from the palette picture. |
4128 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
4128 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
4129 colors assigned to aDevice, such as the preallocated colors of the |
4129 colors assigned to aDevice, such as the preallocated colors of the |
4130 Color class. |
4130 Color class. |
4131 By passing the ditherColors as extra array, this method can |
4131 By passing the ditherColors as extra array, this method can |
4132 also be used to dither an 8bit image into a smaller number of colors, |
4132 also be used to dither an 8bit image into a smaller number of colors, |
4133 for example to create dithered Depth4Images from Depth8Images." |
4133 for example to create dithered Depth4Images from Depth8Images." |
4134 |
4134 |
4135 |pseudoBits f deviceDepth map| |
4135 |pseudoBits f deviceDepth map| |
4136 |
4136 |
4137 deviceDepth := aDevice depth. |
4137 deviceDepth := aDevice depth. |
4138 deviceDepth == 8 ifFalse:[ |
4138 deviceDepth == 8 ifFalse:[ |
4139 (aDevice supportedImageFormatForDepth:8) isNil ifTrue:[ |
4139 (aDevice supportedImageFormatForDepth:8) isNil ifTrue:[ |
4140 ^ nil |
4140 ^ nil |
4141 ] |
4141 ] |
4142 ]. |
4142 ]. |
4143 |
4143 |
4144 pseudoBits := self nearestPaintDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue. |
4144 pseudoBits := self nearestPaintDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue. |
4145 pseudoBits isNil ifTrue:[^ nil]. |
4145 pseudoBits isNil ifTrue:[^ nil]. |
4146 |
4146 |
4151 "/ have to create a funny colorMap, where |
4151 "/ have to create a funny colorMap, where |
4152 "/ color at:index == color colorId:index |
4152 "/ color at:index == color colorId:index |
4153 "/ |
4153 "/ |
4154 map := Array new:256. |
4154 map := Array new:256. |
4155 fixColors do:[:clr | |
4155 fixColors do:[:clr | |
4156 map at:clr colorId + 1 put:clr |
4156 map at:clr colorId + 1 put:clr |
4157 ]. |
4157 ]. |
4158 f colorMap:map. |
4158 f colorMap:map. |
4159 f initGC. |
4159 f initGC. |
4160 f bits:pseudoBits. |
4160 f bits:pseudoBits. |
4161 aDevice |
4161 aDevice |
4162 drawBits:pseudoBits |
4162 drawBits:pseudoBits |
4163 bitsPerPixel:8 |
4163 bitsPerPixel:8 |
4164 depth:deviceDepth |
4164 depth:deviceDepth |
4165 padding:8 |
4165 padding:8 |
4166 width:width height:height |
4166 width:width height:height |
4167 x:0 y:0 |
4167 x:0 y:0 |
4168 into:(f id) x:0 y:0 |
4168 into:(f id) x:0 y:0 |
4169 width:width height:height |
4169 width:width height:height |
4170 with:(f gcId). |
4170 with:(f gcId). |
4171 ^ f |
4171 ^ f |
4172 |
4172 |
4173 " |
4173 " |
4174 example: |
4174 example: |
4175 color reduction from Depth8 to Depth4 (dithering) can be done by: |
4175 color reduction from Depth8 to Depth4 (dithering) can be done by: |
4176 |
4176 |
4177 |img8 reducedImg8 img4 map form| |
4177 |img8 reducedImg8 img4 map form| |
4178 |
4178 |
4179 map := #( |
4179 map := #( |
4180 (0 0 0) |
4180 (0 0 0) |
4181 (0 0 100) |
4181 (0 0 100) |
4182 (0 50 0) |
4182 (0 50 0) |
4183 (0 50 100) |
4183 (0 50 100) |
4184 (0 100 0) |
4184 (0 100 0) |
4185 (0 100 100) |
4185 (0 100 100) |
4186 (100 0 0) |
4186 (100 0 0) |
4187 (100 0 100) |
4187 (100 0 100) |
4188 (100 50 0) |
4188 (100 50 0) |
4189 (100 50 100) |
4189 (100 50 100) |
4190 (100 100 0) |
4190 (100 100 0) |
4191 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
4191 (100 100 100)) collect:[:rgb | (Color red:(rgb at:1) |
4192 green:(rgb at:2) |
4192 green:(rgb at:2) |
4193 blue:(rgb at:3)) onDevice:Display]. |
4193 blue:(rgb at:3)) onDevice:Display]. |
4194 |
4194 |
4195 img8 := Image fromFile:'goodies/bitmaps/claus.gif'. |
4195 img8 := Image fromFile:'goodies/bitmaps/claus.gif'. |
4196 form := img8 asNearestPaintDepth8FormOn:Display |
4196 form := img8 asNearestPaintDepth8FormOn:Display |
4197 colors:map |
4197 colors:map |
4198 nRed:2 |
4198 nRed:2 |
4199 nGreen:3 |
4199 nGreen:3 |
4200 nBlue:2. |
4200 nBlue:2. |
4201 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
4201 img8 := Depth8Image fromForm:form. 'dithered version of original image'. |
4202 img4 := Depth4Image fromImage:img8. |
4202 img4 := Depth4Image fromImage:img8. |
4203 " |
4203 " |
4204 |
4204 |
4205 "Created: 17.6.1996 / 18:47:46 / cg" |
4205 "Created: 17.6.1996 / 18:47:46 / cg" |
4206 "Modified: 17.6.1996 / 18:52:47 / cg" |
4206 "Modified: 17.6.1996 / 18:52:47 / cg" |
4207 ! |
4207 ! |
4208 |
4208 |
4209 asNearestPaintImageDepth:d colors:colors |
4209 asNearestPaintImageDepth:d colors:colors |
4210 "return a threshold image from the receiver picture, using colors in colors." |
4210 "return a threshold image from the receiver picture, using colors in colors." |
4211 |
4211 |
4212 |newBits| |
4212 |newBits| |
4213 |
4213 |
4214 d ~~ 8 ifTrue:[ |
4214 d ~~ 8 ifTrue:[ |
4226 Uses an 8x8 dithermatrix." |
4226 Uses an 8x8 dithermatrix." |
4227 |
4227 |
4228 |depth bits| |
4228 |depth bits| |
4229 |
4229 |
4230 depth := aDevice depth. |
4230 depth := aDevice depth. |
4231 (depth == 1 |
4231 (depth == 1 |
4232 or:[aDevice hasGrayscales not]) ifTrue:[ |
4232 or:[aDevice hasGrayscales not]) ifTrue:[ |
4233 "/ for monochrome, there is highly specialized |
4233 "/ for monochrome, there is highly specialized |
4234 "/ monochrome dither code available |
4234 "/ monochrome dither code available |
4235 |
4235 |
4236 ^ self asOrderedDitheredMonochromeFormOn:aDevice |
4236 ^ self asOrderedDitheredMonochromeFormOn:aDevice |
4260 |dither| |
4260 |dither| |
4261 |
4261 |
4262 dither := self class orderedDitherMatrixOfSize:8. |
4262 dither := self class orderedDitherMatrixOfSize:8. |
4263 |
4263 |
4264 (depth == 1) ifTrue:[ |
4264 (depth == 1) ifTrue:[ |
4265 "/ for monochrome, there is highly specialized |
4265 "/ for monochrome, there is highly specialized |
4266 "/ monochrome dither code available |
4266 "/ monochrome dither code available |
4267 |
4267 |
4268 ^ Depth1Image |
4268 ^ Depth1Image |
4269 width:width |
4269 width:width |
4270 height:height |
4270 height:height |
4271 fromArray:( |
4271 fromArray:( |
4272 self |
4272 self |
4273 orderedDitheredMonochromeBitsWithDitherMatrix:dither |
4273 orderedDitheredMonochromeBitsWithDitherMatrix:dither |
4274 ditherWidth:8) |
4274 ditherWidth:8) |
4275 ]. |
4275 ]. |
4276 |
4276 |
4277 ^ (self class implementorForDepth:depth) |
4277 ^ (self class implementorForDepth:depth) |
4278 width:width |
4278 width:width |
4279 height:height |
4279 height:height |
4280 fromArray:( |
4280 fromArray:( |
4281 self |
4281 self |
4282 orderedDitheredGrayBitsWithDitherMatrix:dither |
4282 orderedDitheredGrayBitsWithDitherMatrix:dither |
4283 ditherWidth:8 |
4283 ditherWidth:8 |
4284 depth:depth) |
4284 depth:depth) |
4285 |
4285 |
4286 " |
4286 " |
4287 |i i1 i2 i4 i8| |
4287 |i i1 i2 i4 i8| |
4288 |
4288 |
4289 i := Image fromFile:'goodies/bitmaps/gifImages/claus.gif'. |
4289 i := Image fromFile:'goodies/bitmaps/gifImages/claus.gif'. |
4333 "/ |
4333 "/ |
4334 "/ could look at the image and decide upon the number of |
4334 "/ could look at the image and decide upon the number of |
4335 "/ distinct colors present. Use 8x8 for high-number, |
4335 "/ distinct colors present. Use 8x8 for high-number, |
4336 "/ 4x4 for small number of colors ... |
4336 "/ 4x4 for small number of colors ... |
4337 |
4337 |
4338 ^ self |
4338 ^ self |
4339 asOrderedDitheredMonochromeFormOn:aDevice |
4339 asOrderedDitheredMonochromeFormOn:aDevice |
4340 ditherMatrix:(self class orderedDitherMatrixOfSize:4) |
4340 ditherMatrix:(self class orderedDitherMatrixOfSize:4) |
4341 ditherWidth:4 |
4341 ditherWidth:4 |
4342 |
4342 |
4343 "/ ^ self |
4343 "/ ^ self |
4344 "/ asOrderedDitheredMonochromeFormOn:aDevice |
4344 "/ asOrderedDitheredMonochromeFormOn:aDevice |
4345 "/ ditherMatrix:(self class orderedDitherMatrixOfSize:8) |
4345 "/ ditherMatrix:(self class orderedDitherMatrixOfSize:8) |
4346 "/ ditherWidth:8 |
4346 "/ ditherWidth:8 |
4347 |
4347 |
4348 " |
4348 " |
4349 |i f| |
4349 |i f| |
4423 "/ |
4423 "/ |
4424 "/ could look at the image and decide upon the number of |
4424 "/ could look at the image and decide upon the number of |
4425 "/ distinct colors present. Use 8x8 for high-number, |
4425 "/ distinct colors present. Use 8x8 for high-number, |
4426 "/ 4x4 for small number of colors ... |
4426 "/ 4x4 for small number of colors ... |
4427 |
4427 |
4428 ^ self |
4428 ^ self |
4429 asOrderedDitheredMonochromeImageWithDitherMatrix:(self class orderedDitherMatrixOfSize:4) |
4429 asOrderedDitheredMonochromeImageWithDitherMatrix:(self class orderedDitherMatrixOfSize:4) |
4430 ditherWidth:4 |
4430 ditherWidth:4 |
4431 |
4431 |
4432 "/ ^ self |
4432 "/ ^ self |
4433 "/ asOrderedDitheredMonochromeImageWithDitherMatrix:(self class orderedDitherMatrixOfSize:8) |
4433 "/ asOrderedDitheredMonochromeImageWithDitherMatrix:(self class orderedDitherMatrixOfSize:8) |
4434 "/ ditherWidth:8 |
4434 "/ ditherWidth:8 |
4435 |
4435 |
4436 " |
4436 " |
4437 |i| |
4437 |i| |
4481 |
4481 |
4482 |i| |
4482 |i| |
4483 |
4483 |
4484 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4484 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4485 i |
4485 i |
4486 asOrderedDitheredMonochromeImageWithDitherMatrix:(Image orderedDitherMatrixOfSize:4) |
4486 asOrderedDitheredMonochromeImageWithDitherMatrix:(Image orderedDitherMatrixOfSize:4) |
4487 ditherWidth:4 |
4487 ditherWidth:4 |
4488 " |
4488 " |
4489 |
4489 |
4490 "order-6 dither: |
4490 "order-6 dither: |
4491 |
4491 |
4492 |i| |
4492 |i| |
4493 |
4493 |
4494 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4494 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4495 i |
4495 i |
4496 asOrderedDitheredMonochromeImageWithDitherMatrix:(Image orderedDitherMatrixOfSize:8) |
4496 asOrderedDitheredMonochromeImageWithDitherMatrix:(Image orderedDitherMatrixOfSize:8) |
4497 ditherWidth:8 |
4497 ditherWidth:8 |
4498 " |
4498 " |
4499 |
4499 |
4500 |
4500 |
4501 "thresholding at:0.5 (all above 0.5 becomes white): |
4501 "thresholding at:0.5 (all above 0.5 becomes white): |
4502 |
4502 |
4503 |i| |
4503 |i| |
4504 |
4504 |
4505 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4505 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4506 i |
4506 i |
4507 asOrderedDitheredMonochromeImageWithDitherMatrix:(ByteArray new:16 withAll:8) |
4507 asOrderedDitheredMonochromeImageWithDitherMatrix:(ByteArray new:16 withAll:8) |
4508 ditherWidth:4 |
4508 ditherWidth:4 |
4509 " |
4509 " |
4510 |
4510 |
4511 "thresholding at: 0.25 (all above 0.25 becomes white): |
4511 "thresholding at: 0.25 (all above 0.25 becomes white): |
4512 |
4512 |
4513 |i| |
4513 |i| |
4514 |
4514 |
4515 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4515 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4516 i |
4516 i |
4517 asOrderedDitheredMonochromeImageWithDitherMatrix:(ByteArray new:16 withAll:3) |
4517 asOrderedDitheredMonochromeImageWithDitherMatrix:(ByteArray new:16 withAll:3) |
4518 ditherWidth:4 |
4518 ditherWidth:4 |
4519 " |
4519 " |
4520 |
4520 |
4521 "thresholding at: 0.75 (all above 0.75 becomes white): |
4521 "thresholding at: 0.75 (all above 0.75 becomes white): |
4522 |
4522 |
4523 |i| |
4523 |i| |
4524 |
4524 |
4525 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4525 i := Image fromFile:'goodies/bitmaps/gifImages/garfield.gif'. |
4526 i |
4526 i |
4527 asOrderedDitheredMonochromeImageWithDitherMatrix:(ByteArray new:16 withAll:11) |
4527 asOrderedDitheredMonochromeImageWithDitherMatrix:(ByteArray new:16 withAll:11) |
4528 ditherWidth:4 |
4528 ditherWidth:4 |
4529 " |
4529 " |
4530 |
4530 |
4531 "Modified: 7.6.1996 / 17:23:47 / cg" |
4531 "Modified: 7.6.1996 / 17:23:47 / cg" |
4532 ! |
4532 ! |
4533 |
4533 |
4534 asPseudoFormQuickOn:aDevice |
4534 asPseudoFormQuickOn:aDevice |
4535 "return a pseudo-deviceForm from the image. |
4535 "return a pseudo-deviceForm from the image. |
4536 Fail if any color is not available (i.e. do not dither)." |
4536 Fail if any color is not available (i.e. do not dither)." |
4537 |
4537 |
4538 |f d |
4538 |f d |
4539 temp temp8 bits clr cMap idMap |
4539 temp temp8 bits clr cMap idMap |
4540 w "{ Class: SmallInteger }" |
4540 w "{ Class: SmallInteger }" |
4541 h "{ Class: SmallInteger }" |
4541 h "{ Class: SmallInteger }" |
4542 dDev "{ Class: SmallInteger }" |
4542 dDev "{ Class: SmallInteger }" |
4543 nClr "{ Class: SmallInteger }" |
4543 nClr "{ Class: SmallInteger }" |
4544 bytesPerLine "{ Class: SmallInteger }" |
4544 bytesPerLine "{ Class: SmallInteger }" |
4545 usedColors pix fmt bytes| |
4545 usedColors pix fmt bytes| |
4546 |
4546 |
4547 d := self depth. |
4547 d := self depth. |
4548 (d == 1 |
4548 (d == 1 |
4616 |
4616 |
4617 (d == 8 and:[dDev == 8]) ifTrue:[ |
4617 (d == 8 and:[dDev == 8]) ifTrue:[ |
4618 "/ only translate |
4618 "/ only translate |
4619 temp := ByteArray uninitializedNew:(w * h). |
4619 temp := ByteArray uninitializedNew:(w * h). |
4620 bytes expandPixels:8 "xlate only" |
4620 bytes expandPixels:8 "xlate only" |
4621 width:w |
4621 width:w |
4622 height:h |
4622 height:h |
4623 into:temp |
4623 into:temp |
4624 mapping:idMap. |
4624 mapping:idMap. |
4625 ] ifFalse:[ |
4625 ] ifFalse:[ |
4626 "/ stupid: expandPixels can only handle any-to-8 |
4626 "/ stupid: expandPixels can only handle any-to-8 |
4631 "/ then from 8 to the device depth. |
4631 "/ then from 8 to the device depth. |
4632 |
4632 |
4633 d ~~ 8 ifTrue:[ |
4633 d ~~ 8 ifTrue:[ |
4634 temp8 := ByteArray uninitializedNew:(w * h). |
4634 temp8 := ByteArray uninitializedNew:(w * h). |
4635 |
4635 |
4636 bytes expandPixels:d |
4636 bytes expandPixels:d |
4637 width:w |
4637 width:w |
4638 height:h |
4638 height:h |
4639 into:temp8 |
4639 into:temp8 |
4640 mapping:idMap. |
4640 mapping:idMap. |
4641 idMap := nil. |
4641 idMap := nil. |
4642 ] ifFalse:[ |
4642 ] ifFalse:[ |
4644 ]. |
4644 ]. |
4645 |
4645 |
4646 dDev ~~ 8 ifTrue:[ |
4646 dDev ~~ 8 ifTrue:[ |
4647 temp := ByteArray uninitializedNew:(bytesPerLine * h). |
4647 temp := ByteArray uninitializedNew:(bytesPerLine * h). |
4648 |
4648 |
4649 temp8 compressPixels:dDev |
4649 temp8 compressPixels:dDev |
4650 width:w |
4650 width:w |
4651 height:h |
4651 height:h |
4652 into:temp |
4652 into:temp |
4653 mapping:idMap. |
4653 mapping:idMap. |
4654 ] ifFalse:[ |
4654 ] ifFalse:[ |
4655 temp := temp8 |
4655 temp := temp8 |
4657 ]. |
4657 ]. |
4658 |
4658 |
4659 f := Form width:w height:h depth:dDev on:aDevice. |
4659 f := Form width:w height:h depth:dDev on:aDevice. |
4660 f isNil ifTrue:[^ nil]. |
4660 f isNil ifTrue:[^ nil]. |
4661 |
4661 |
4662 f colorMap:cMap. |
4662 f colorMap:cMap. |
4663 f initGC. |
4663 f initGC. |
4664 |
4664 |
4665 aDevice |
4665 aDevice |
4666 drawBits:temp |
4666 drawBits:temp |
4667 depth:dDev |
4667 depth:dDev |
4668 padding:8 |
4668 padding:8 |
4669 width:w |
4669 width:w |
4670 height:h |
4670 height:h |
4671 x:0 y:0 |
4671 x:0 y:0 |
4672 into:(f id) x:0 y:0 |
4672 into:(f id) x:0 y:0 |
4673 width:w |
4673 width:w |
4674 height:h |
4674 height:h |
4675 with:(f gcId). |
4675 with:(f gcId). |
4676 |
4676 |
4677 ^ f |
4677 ^ f |
4678 |
4678 |
4679 " |
4679 " |
4680 ( |
4680 ( |
4681 (((Depth4Image |
4681 (((Depth4Image |
4682 width:4 |
4682 width:4 |
4683 height:4 |
4683 height:4 |
4684 fromArray:#[ |
4684 fromArray:#[ |
4685 16r01 16r23 |
4685 16r01 16r23 |
4686 16r45 16r67 |
4686 16r45 16r67 |
4687 16r89 16rab |
4687 16r89 16rab |
4688 16rcd 16ref |
4688 16rcd 16ref |
4689 ])) |
4689 ])) |
4690 magnifiedBy:30 |
4690 magnifiedBy:30 |
4691 ) |
4691 ) |
4692 asPseudoFormQuickOn:Display |
4692 asPseudoFormQuickOn:Display |
4693 ) inspect |
4693 ) inspect |
4732 |
4732 |
4733 " |
4733 " |
4734 |i| |
4734 |i| |
4735 |
4735 |
4736 i := Depth4Image |
4736 i := Depth4Image |
4737 width:4 |
4737 width:4 |
4738 height:4 |
4738 height:4 |
4739 fromArray:#[ |
4739 fromArray:#[ |
4740 16r01 16r23 |
4740 16r01 16r23 |
4741 16r45 16r67 |
4741 16r45 16r67 |
4742 16r89 16rab |
4742 16r89 16rab |
4743 16rcd 16ref |
4743 16rcd 16ref |
4744 ]. |
4744 ]. |
4745 i := i magnifiedBy:30. |
4745 i := i magnifiedBy:30. |
4746 i inspect. |
4746 i inspect. |
4747 i asStevensonArceDitheredMonochromeImage inspect. |
4747 i asStevensonArceDitheredMonochromeImage inspect. |
4748 i asOrderedDitheredMonochromeImage inspect. |
4748 i asOrderedDitheredMonochromeImage inspect. |
4749 " |
4749 " |
4759 |
4759 |
4760 (depth := aDevice depth) == 1 ifTrue:[ |
4760 (depth := aDevice depth) == 1 ifTrue:[ |
4761 ^ self asThresholdMonochromeFormOn:aDevice |
4761 ^ self asThresholdMonochromeFormOn:aDevice |
4762 ]. |
4762 ]. |
4763 |
4763 |
4764 ^ self |
4764 ^ self |
4765 makeDeviceGrayPixmapOn:aDevice |
4765 makeDeviceGrayPixmapOn:aDevice |
4766 depth:depth |
4766 depth:depth |
4767 fromArray:(self |
4767 fromArray:(self |
4768 orderedDitheredGrayBitsWithDitherMatrix:#[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8] |
4768 orderedDitheredGrayBitsWithDitherMatrix:#[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8] |
4769 ditherWidth:4 |
4769 ditherWidth:4 |
4770 depth:depth) |
4770 depth:depth) |
4771 |
4771 |
4830 ! |
4830 ! |
4831 |
4831 |
4832 asThresholdMonochromeFormOn:aDevice |
4832 asThresholdMonochromeFormOn:aDevice |
4833 "return a threshold monochrome form from the image." |
4833 "return a threshold monochrome form from the image." |
4834 |
4834 |
4835 ^ self |
4835 ^ self |
4836 asOrderedDitheredMonochromeFormOn:aDevice |
4836 asOrderedDitheredMonochromeFormOn:aDevice |
4837 ditherMatrix:#[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8] |
4837 ditherMatrix:#[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8] |
4838 ditherWidth:4 |
4838 ditherWidth:4 |
4839 |
4839 |
4840 " |
4840 " |
4841 |i| |
4841 |i| |
5041 ! |
5041 ! |
5042 |
5042 |
5043 fromImage:anImage |
5043 fromImage:anImage |
5044 "setup the receiver from another image. |
5044 "setup the receiver from another image. |
5045 Color precision may be lost, if conversion is from a higher depth |
5045 Color precision may be lost, if conversion is from a higher depth |
5046 image. |
5046 image. |
5047 WARNING: |
5047 WARNING: |
5048 This implementation is a slow fallback (the loop over the |
5048 This implementation is a slow fallback (the loop over the |
5049 source pixels is very slow). If this method is used heavily, you |
5049 source pixels is very slow). If this method is used heavily, you |
5050 may want to redefine it in concrete subclasses for common source images." |
5050 may want to redefine it in concrete subclasses for common source images." |
5051 |
5051 |
5053 ! |
5053 ! |
5054 |
5054 |
5055 fromImage:anImage photometric:photometricOrNil |
5055 fromImage:anImage photometric:photometricOrNil |
5056 "setup the receiver from another image and optionally set the photometric. |
5056 "setup the receiver from another image and optionally set the photometric. |
5057 Color precision may be lost, if conversion is from a higher depth |
5057 Color precision may be lost, if conversion is from a higher depth |
5058 image. |
5058 image. |
5059 WARNING: |
5059 WARNING: |
5060 This implementation is a slow fallback (the loop over the |
5060 This implementation is a slow fallback (the loop over the |
5061 source pixels is very slow). If this method is used heavily, you |
5061 source pixels is very slow). If this method is used heavily, you |
5062 may want to redefine it in concrete subclasses for common source images." |
5062 may want to redefine it in concrete subclasses for common source images." |
5063 |
5063 |
5185 |
5185 |
5186 ((photometric == anImage photometric) |
5186 ((photometric == anImage photometric) |
5187 and:[self bitsPerPixel = anImage bitsPerPixel |
5187 and:[self bitsPerPixel = anImage bitsPerPixel |
5188 and:[colorMap = anImage colorMap]]) ifTrue:[ |
5188 and:[colorMap = anImage colorMap]]) ifTrue:[ |
5189 "/ can do it by value |
5189 "/ can do it by value |
5190 anImage |
5190 anImage |
5191 valuesFromX:xL y:yT toX:xR y:yB |
5191 valuesFromX:xL y:yT toX:xR y:yB |
5192 do:[:x :y :pixelValue | |
5192 do:[:x :y :pixelValue | |
5193 self pixelAtX:x-xL y:y-yT put:pixelValue. |
5193 self pixelAtX:x-xL y:y-yT put:pixelValue. |
5194 ] |
5194 ] |
5195 ] ifFalse:[ |
5195 ] ifFalse:[ |
5196 "/ must do it by colors |
5196 "/ must do it by colors |
5197 anImage |
5197 anImage |
5198 colorsFromX:xL y:yT toX:xR y:yB |
5198 colorsFromX:xL y:yT toX:xR y:yB |
5199 do:[:x :y :clr | |
5199 do:[:x :y :clr | |
5200 self colorAtX:x-xL y:y-yT put:clr. |
5200 self colorAtX:x-xL y:y-yT put:clr. |
5201 ] |
5201 ] |
5202 ]. |
5202 ]. |
5205 anImage mask depth == 1 ifTrue:[ |
5205 anImage mask depth == 1 ifTrue:[ |
5206 maskClass := ImageMask |
5206 maskClass := ImageMask |
5207 ] ifFalse:[ |
5207 ] ifFalse:[ |
5208 maskClass := anImage mask class. |
5208 maskClass := anImage mask class. |
5209 ]. |
5209 ]. |
5210 mask := maskClass new |
5210 mask := maskClass new |
5211 fromSubImage:anImage mask in:aRectangle |
5211 fromSubImage:anImage mask in:aRectangle |
5212 ]. |
5212 ]. |
5213 |
5213 |
5214 " |
5214 " |
5215 |i i2 i4 i8 i16 i24| |
5215 |i i2 i4 i8 i16 i24| |
5322 ! |
5322 ! |
5323 |
5323 |
5324 greyImageAsPseudoFormOn:aDevice |
5324 greyImageAsPseudoFormOn:aDevice |
5325 "return an 8-bit pseudo Form from the grey image" |
5325 "return an 8-bit pseudo Form from the grey image" |
5326 |
5326 |
5327 |wideBits pictureDepth f map |
5327 |wideBits pictureDepth f map |
5328 colorMap usedColors nUsed aColor |
5328 colorMap usedColors nUsed aColor |
5329 nColors "{ Class: SmallInteger }" |
5329 nColors "{ Class: SmallInteger }" |
5330 range id |
5330 range id |
5331 cube nR nG nB grayColors |
5331 cube nR nG nB grayColors |
5332 fit| |
5332 fit| |
5333 |
5333 |
5345 to avoid allocating too many colors" |
5345 to avoid allocating too many colors" |
5346 |
5346 |
5347 (grayColors := aDevice fixGrayColors) notNil ifTrue:[ |
5347 (grayColors := aDevice fixGrayColors) notNil ifTrue:[ |
5348 DitherAlgorithm == #floydSteinberg ifTrue:[ |
5348 DitherAlgorithm == #floydSteinberg ifTrue:[ |
5349 f := self |
5349 f := self |
5350 asFloydSteinbergDitheredDepth8FormOn:aDevice |
5350 asFloydSteinbergDitheredDepth8FormOn:aDevice |
5351 colors:grayColors |
5351 colors:grayColors |
5352 ]. |
5352 ]. |
5353 f notNil ifTrue:[^ f]. |
5353 f notNil ifTrue:[^ f]. |
5354 ]. |
5354 ]. |
5355 |
5355 |
5356 (cube := aDevice fixColors) notNil ifTrue:[ |
5356 (cube := aDevice fixColors) notNil ifTrue:[ |
5358 nG := aDevice numFixGreen. |
5358 nG := aDevice numFixGreen. |
5359 nB := aDevice numFixBlue. |
5359 nB := aDevice numFixBlue. |
5360 |
5360 |
5361 DitherAlgorithm == #floydSteinberg ifTrue:[ |
5361 DitherAlgorithm == #floydSteinberg ifTrue:[ |
5362 f := self |
5362 f := self |
5363 asFloydSteinbergDitheredDepth8FormOn:aDevice |
5363 asFloydSteinbergDitheredDepth8FormOn:aDevice |
5364 colors:cube |
5364 colors:cube |
5365 nRed:nR |
5365 nRed:nR |
5366 nGreen:nG |
5366 nGreen:nG |
5367 nBlue:nB. |
5367 nBlue:nB. |
5368 ] ifFalse:[ |
5368 ] ifFalse:[ |
5369 f := self |
5369 f := self |
5370 asNearestPaintDepth8FormOn:aDevice |
5370 asNearestPaintDepth8FormOn:aDevice |
5371 colors:cube |
5371 colors:cube |
5372 nRed:nR |
5372 nRed:nR |
5373 nGreen:nG |
5373 nGreen:nG |
5374 nBlue:nB. |
5374 nBlue:nB. |
5375 ]. |
5375 ]. |
5376 f notNil ifTrue:[^ f]. |
5376 f notNil ifTrue:[^ f]. |
5421 "/ Must dither. |
5421 "/ Must dither. |
5422 |
5422 |
5423 ]. |
5423 ]. |
5424 |
5424 |
5425 "expand & translate" |
5425 "expand & translate" |
5426 self bits |
5426 self bits |
5427 expandPixels:pictureDepth |
5427 expandPixels:pictureDepth |
5428 width:width height:height |
5428 width:width height:height |
5429 into:wideBits |
5429 into:wideBits |
5430 mapping:map. |
5430 mapping:map. |
5431 |
5431 |
5432 f := Form width:width height:height depth:8 on:aDevice. |
5432 f := Form width:width height:height depth:8 on:aDevice. |
5433 f isNil ifTrue:[^ nil]. |
5433 f isNil ifTrue:[^ nil]. |
5434 f colorMap:colorMap. |
5434 f colorMap:colorMap. |
5435 f initGC. |
5435 f initGC. |
5436 aDevice |
5436 aDevice |
5437 drawBits:wideBits |
5437 drawBits:wideBits |
5438 depth:8 |
5438 depth:8 |
5439 padding:8 |
5439 padding:8 |
5440 width:width height:height |
5440 width:width height:height |
5441 x:0 y:0 |
5441 x:0 y:0 |
5442 into:(f id) |
5442 into:(f id) |
5443 x:0 y:0 |
5443 x:0 y:0 |
5444 width:width height:height |
5444 width:width height:height |
5445 with:(f gcId). |
5445 with:(f gcId). |
5446 ^ f |
5446 ^ f |
5447 |
5447 |
5448 "Modified: 19.10.1997 / 05:19:44 / cg" |
5448 "Modified: 19.10.1997 / 05:19:44 / cg" |
5449 ! |
5449 ! |
5450 |
5450 |
5451 greyImageAsTrueColorFormOn:aDevice |
5451 greyImageAsTrueColorFormOn:aDevice |
5452 "return a true-color device-form for the grey-image receiver. |
5452 "return a true-color device-form for the grey-image receiver. |
5453 TODO: the pixel loops ought to be implemented as inline primitive code ..." |
5453 TODO: the pixel loops ought to be implemented as inline primitive code ..." |
5454 |
5454 |
5455 |depth |
5455 |depth |
5456 myDepth "{ Class: SmallInteger }" |
5456 myDepth "{ Class: SmallInteger }" |
5457 nColors "{ Class: SmallInteger }" |
5457 nColors "{ Class: SmallInteger }" |
5458 colorValues |
5458 colorValues |
5459 scaleDown |
5459 scaleDown |
5460 scaleRed "{ Class: SmallInteger }" |
5460 scaleRed "{ Class: SmallInteger }" |
5461 scaleGreen "{ Class: SmallInteger }" |
5461 scaleGreen "{ Class: SmallInteger }" |
5462 scaleBlue "{ Class: SmallInteger }" |
5462 scaleBlue "{ Class: SmallInteger }" |
5463 redShift "{ Class: SmallInteger }" |
5463 redShift "{ Class: SmallInteger }" |
5464 blueShift "{ Class: SmallInteger }" |
5464 blueShift "{ Class: SmallInteger }" |
5465 greenShift "{ Class: SmallInteger }" |
5465 greenShift "{ Class: SmallInteger }" |
5466 form bestFormat usedDeviceDepth usedDeviceBitsPerPixel imageBits |
5466 form bestFormat usedDeviceDepth usedDeviceBitsPerPixel imageBits |
5467 greyValue "{ Class: SmallInteger }" |
5467 greyValue "{ Class: SmallInteger }" |
5468 h "{ Class: SmallInteger }" |
5468 h "{ Class: SmallInteger }" |
5469 w "{ Class: SmallInteger }" |
5469 w "{ Class: SmallInteger }" |
5470 pixelArray newPixelArray i| |
5470 pixelArray newPixelArray i| |
5471 |
5471 |
5542 |
5542 |
5543 form := Form width:width height:height depth:usedDeviceDepth on:aDevice. |
5543 form := Form width:width height:height depth:usedDeviceDepth on:aDevice. |
5544 form isNil ifTrue:[^ nil]. |
5544 form isNil ifTrue:[^ nil]. |
5545 form initGC. |
5545 form initGC. |
5546 |
5546 |
5547 form |
5547 form |
5548 copyBitsFrom:imageBits |
5548 copyBitsFrom:imageBits |
5549 bitsPerPixel:usedDeviceBitsPerPixel |
5549 bitsPerPixel:usedDeviceBitsPerPixel |
5550 depth:usedDeviceDepth |
5550 depth:usedDeviceDepth |
5551 padding:8 |
5551 padding:8 |
5552 width:width height:height |
5552 width:width height:height |
5553 x:0 y:0 |
5553 x:0 y:0 |
5554 toX:0 y:0. |
5554 toX:0 y:0. |
5555 |
5555 |
5556 ^ form |
5556 ^ form |
5557 |
5557 |
5558 "Created: 20.10.1995 / 22:05:10 / cg" |
5558 "Created: 20.10.1995 / 22:05:10 / cg" |
5559 "Modified: 24.4.1997 / 23:11:16 / cg" |
5559 "Modified: 24.4.1997 / 23:11:16 / cg" |
5604 "return a pseudo-deviceForm from the palette image." |
5604 "return a pseudo-deviceForm from the palette image." |
5605 |
5605 |
5606 |tempImage d temp8| |
5606 |tempImage d temp8| |
5607 |
5607 |
5608 d := self depth. |
5608 d := self depth. |
5609 (#(1 2 4 8) includes:d) ifTrue:[ |
5609 (#(1 2 4 8) includes:d) ifTrue:[ |
5610 " |
5610 " |
5611 fallback code for some depth's: |
5611 fallback code for some depth's: |
5612 create a temporary Depth8Image and use its conversion method |
5612 create a temporary Depth8Image and use its conversion method |
5613 " |
5613 " |
5614 temp8 := ByteArray uninitializedNew:(width * height). |
5614 temp8 := ByteArray uninitializedNew:(width * height). |
5615 |
5615 |
5616 self bits |
5616 self bits |
5617 expandPixels:d |
5617 expandPixels:d |
5618 width:width height:height |
5618 width:width height:height |
5619 into:temp8 |
5619 into:temp8 |
5620 mapping:nil. |
5620 mapping:nil. |
5621 |
5621 |
5622 tempImage := Image width:width height:height depth:8 fromArray:temp8. |
5622 tempImage := Image width:width height:height depth:8 fromArray:temp8. |
5627 ! |
5627 ! |
5628 |
5628 |
5629 paletteImageAsTrueColorFormOn:aDevice |
5629 paletteImageAsTrueColorFormOn:aDevice |
5630 "return a true-color device-form for the palette-image receiver." |
5630 "return a true-color device-form for the palette-image receiver." |
5631 |
5631 |
5632 |depth |
5632 |depth |
5633 nColors "{ Class: SmallInteger }" |
5633 nColors "{ Class: SmallInteger }" |
5634 h "{ Class: SmallInteger }" |
5634 h "{ Class: SmallInteger }" |
5635 pixel "{ Class: SmallInteger }" |
5635 pixel "{ Class: SmallInteger }" |
5636 colorValues |
5636 colorValues |
5637 scaleRed scaleGreen scaleBlue redShift greenShift blueShift |
5637 scaleRed scaleGreen scaleBlue redShift greenShift blueShift |
5638 form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel |
5638 form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel |
5639 i pixelArray newPixelArray |
5639 i pixelArray newPixelArray |
5640 clr r g b rv gv bv v "{ Class: SmallInteger }" | |
5640 clr r g b rv gv bv v "{ Class: SmallInteger }" | |
5641 |
5641 |
5642 "/ this is a slow fallback method; this ought to be |
5642 "/ this is a slow fallback method; this ought to be |
5643 "/ redefined in DepthxImage for more performance. |
5643 "/ redefined in DepthxImage for more performance. |
5645 depth := aDevice depth. |
5645 depth := aDevice depth. |
5646 |
5646 |
5647 bestFormat := self bestSupportedImageFormatFor:aDevice. |
5647 bestFormat := self bestSupportedImageFormatFor:aDevice. |
5648 usedDeviceDepth := bestFormat at:#depth. |
5648 usedDeviceDepth := bestFormat at:#depth. |
5649 usedDeviceDepth == 1 ifTrue:[ |
5649 usedDeviceDepth == 1 ifTrue:[ |
5650 ^ self asMonochromeFormOn:aDevice. |
5650 ^ self asMonochromeFormOn:aDevice. |
5651 ]. |
5651 ]. |
5652 usedDeviceBitsPerPixel := bestFormat at:#bitsPerPixel. |
5652 usedDeviceBitsPerPixel := bestFormat at:#bitsPerPixel. |
5653 |
5653 |
5654 |
5654 |
5655 scaleRed := ((1 bitShift:aDevice bitsRed) - 1) / 255. |
5655 scaleRed := ((1 bitShift:aDevice bitsRed) - 1) / 255. |
5659 greenShift := aDevice shiftGreen. |
5659 greenShift := aDevice shiftGreen. |
5660 blueShift := aDevice shiftBlue. |
5660 blueShift := aDevice shiftBlue. |
5661 |
5661 |
5662 nColors := colorMap size. |
5662 nColors := colorMap size. |
5663 nColors <= 4096 ifTrue:[ |
5663 nColors <= 4096 ifTrue:[ |
5664 "/ precompute scales to map from 0..100 into devices range |
5664 "/ precompute scales to map from 0..100 into devices range |
5665 "/ (this may be different for the individual components) |
5665 "/ (this may be different for the individual components) |
5666 colorValues := Array uninitializedNew:nColors. |
5666 colorValues := Array uninitializedNew:nColors. |
5667 |
5667 |
5668 1 to:nColors do:[:index | |
5668 1 to:nColors do:[:index | |
5669 r := colorMap redByteAt:index. |
5669 r := colorMap redByteAt:index. |
5670 g := colorMap greenByteAt:index. |
5670 g := colorMap greenByteAt:index. |
5671 b := colorMap blueByteAt:index. |
5671 b := colorMap blueByteAt:index. |
5672 "/ clr := colorMap at:index. |
5672 "/ clr := colorMap at:index. |
5673 true "clr notNil" ifTrue:[ |
5673 true "clr notNil" ifTrue:[ |
5674 "/ r := clr red. |
5674 "/ r := clr red. |
5675 "/ g := clr green. |
5675 "/ g := clr green. |
5676 "/ b := clr blue. |
5676 "/ b := clr blue. |
5677 rv := (r * scaleRed) rounded. |
5677 rv := (r * scaleRed) rounded. |
5678 gv := (g * scaleGreen) rounded. |
5678 gv := (g * scaleGreen) rounded. |
5679 bv := (b * scaleBlue) rounded. |
5679 bv := (b * scaleBlue) rounded. |
5680 |
5680 |
5681 v := rv bitShift:redShift. |
5681 v := rv bitShift:redShift. |
5682 v := v bitOr:(gv bitShift:greenShift). |
5682 v := v bitOr:(gv bitShift:greenShift). |
5683 v := v bitOr:(bv bitShift:blueShift). |
5683 v := v bitOr:(bv bitShift:blueShift). |
5684 colorValues at:index put:v. |
5684 colorValues at:index put:v. |
5685 "/ clr print. ' ' print. |
5685 "/ clr print. ' ' print. |
5686 "/ rv print. ' ' print. gv print. ' ' print. bv print. ' ' print. |
5686 "/ rv print. ' ' print. gv print. ' ' print. bv print. ' ' print. |
5687 "/ ' -> ' print. v printNL. |
5687 "/ ' -> ' print. v printNL. |
5688 |
5688 |
5689 ] |
5689 ] |
5690 ]. |
5690 ]. |
5691 ]. |
5691 ]. |
5692 |
5692 |
5693 "/ the temporary helper image is only needed to allow |
5693 "/ the temporary helper image is only needed to allow |
5694 "/ the rowAt:putAll: calls below. |
5694 "/ the rowAt:putAll: calls below. |
5695 |
5695 |
5704 h := height - 1. |
5704 h := height - 1. |
5705 pixelArray := self pixelArraySpecies new:width. |
5705 pixelArray := self pixelArraySpecies new:width. |
5706 newPixelArray := i pixelArraySpecies new:width. |
5706 newPixelArray := i pixelArraySpecies new:width. |
5707 |
5707 |
5708 colorValues notNil ifTrue:[ |
5708 colorValues notNil ifTrue:[ |
5709 0 to:h do:[:y | |
5709 0 to:h do:[:y | |
5710 self rowAt:y into:pixelArray. |
5710 self rowAt:y into:pixelArray. |
5711 1 to:width do:[:x | |
5711 1 to:width do:[:x | |
5712 pixel := pixelArray at:x. |
5712 pixel := pixelArray at:x. |
5713 newPixelArray at:x put:(colorValues at:pixel + 1). |
5713 newPixelArray at:x put:(colorValues at:pixel + 1). |
5714 ]. |
5714 ]. |
5715 i rowAt:y putAll:newPixelArray. |
5715 i rowAt:y putAll:newPixelArray. |
5716 ]. |
5716 ]. |
5717 ] ifFalse:[ |
5717 ] ifFalse:[ |
5718 0 to:h do:[:y | |
5718 0 to:h do:[:y | |
5719 self rowAt:y into:pixelArray. |
5719 self rowAt:y into:pixelArray. |
5720 1 to:width do:[:x | |
5720 1 to:width do:[:x | |
5721 |
5721 |
5722 pixel := pixelArray at:x. |
5722 pixel := pixelArray at:x. |
5723 clr := self colorFromValue:pixel. |
5723 clr := self colorFromValue:pixel. |
5724 r := clr redByte. |
5724 r := clr redByte. |
5725 g := clr greenByte. |
5725 g := clr greenByte. |
5726 b := clr blueByte. |
5726 b := clr blueByte. |
5727 |
5727 |
5728 rv := (r * scaleRed) rounded. |
5728 rv := (r * scaleRed) rounded. |
5729 gv := (g * scaleGreen) rounded. |
5729 gv := (g * scaleGreen) rounded. |
5730 bv := (b * scaleBlue) rounded. |
5730 bv := (b * scaleBlue) rounded. |
5731 |
5731 |
5732 v := rv bitShift:redShift. |
5732 v := rv bitShift:redShift. |
5733 v := v bitOr:(gv bitShift:greenShift). |
5733 v := v bitOr:(gv bitShift:greenShift). |
5734 v := v bitOr:(bv bitShift:blueShift). |
5734 v := v bitOr:(bv bitShift:blueShift). |
5735 |
5735 |
5736 newPixelArray at:x put:v. |
5736 newPixelArray at:x put:v. |
5737 ]. |
5737 ]. |
5738 i rowAt:y putAll:newPixelArray. |
5738 i rowAt:y putAll:newPixelArray. |
5739 ]. |
5739 ]. |
5740 ]. |
5740 ]. |
5741 |
5741 |
5742 form := Form width:width height:height depth:usedDeviceDepth on:aDevice. |
5742 form := Form width:width height:height depth:usedDeviceDepth on:aDevice. |
5743 form isNil ifTrue:[^ nil]. |
5743 form isNil ifTrue:[^ nil]. |
5744 form initGC. |
5744 form initGC. |
5745 |
5745 |
5746 form |
5746 form |
5747 copyBitsFrom:imageBits |
5747 copyBitsFrom:imageBits |
5748 bitsPerPixel:usedDeviceBitsPerPixel |
5748 bitsPerPixel:usedDeviceBitsPerPixel |
5749 depth:usedDeviceDepth |
5749 depth:usedDeviceDepth |
5750 padding:8 |
5750 padding:8 |
5751 width:width height:height |
5751 width:width height:height |
5752 x:0 y:0 |
5752 x:0 y:0 |
5753 toX:0 y:0. |
5753 toX:0 y:0. |
5754 |
5754 |
5755 ^ form |
5755 ^ form |
5756 |
5756 |
5757 "Modified: / 24.7.1998 / 00:56:14 / cg" |
5757 "Modified: / 24.7.1998 / 00:56:14 / cg" |
5758 ! ! |
5758 ! ! |
5759 |
5759 |
5760 !Image methodsFor:'converting rgb images'! |
5760 !Image methodsFor:'converting rgb images'! |
5761 |
5761 |
5762 asDitheredTrueColor8FormOn:aDevice |
5762 asDitheredTrueColor8FormOn:aDevice |
5763 "convert an rgb image to a dithered depth8-form on aDevice. |
5763 "convert an rgb image to a dithered depth8-form on aDevice. |
5764 Return the device-form. |
5764 Return the device-form. |
5765 This method is only valid for trueColor displays." |
5765 This method is only valid for trueColor displays." |
5766 |
5766 |
5767 |fixColors pixel |
5767 |fixColors pixel |
5768 dstIdx "{ Class: SmallInteger }" |
5768 dstIdx "{ Class: SmallInteger }" |
5769 shiftRed "{ Class: SmallInteger }" |
5769 shiftRed "{ Class: SmallInteger }" |
5795 ] |
5795 ] |
5796 ] |
5796 ] |
5797 ]. |
5797 ]. |
5798 |
5798 |
5799 ^ self |
5799 ^ self |
5800 asFloydSteinbergDitheredDepth8FormOn:aDevice |
5800 asFloydSteinbergDitheredDepth8FormOn:aDevice |
5801 colors:fixColors |
5801 colors:fixColors |
5802 nRed:nRed nGreen:nGreen nBlue:nBlue |
5802 nRed:nRed nGreen:nGreen nBlue:nBlue |
5803 |
5803 |
5804 "Created: 14.6.1996 / 17:23:52 / cg" |
5804 "Created: 14.6.1996 / 17:23:52 / cg" |
5805 "Modified: 23.6.1997 / 15:22:36 / cg" |
5805 "Modified: 23.6.1997 / 15:22:36 / cg" |
5806 ! |
5806 ! |
5887 'Image [warning]: display bitmap creation failed' errorPrintCR. |
5887 'Image [warning]: display bitmap creation failed' errorPrintCR. |
5888 ^ nil |
5888 ^ nil |
5889 ]. |
5889 ]. |
5890 form initGC. |
5890 form initGC. |
5891 |
5891 |
5892 form |
5892 form |
5893 copyBitsFrom:self bits |
5893 copyBitsFrom:self bits |
5894 bitsPerPixel:usedDeviceBitsPerPixel |
5894 bitsPerPixel:usedDeviceBitsPerPixel |
5895 depth:usedDeviceDepth |
5895 depth:usedDeviceDepth |
5896 padding:8 |
5896 padding:8 |
5897 width:width height:height |
5897 width:width height:height |
5898 x:0 y:0 |
5898 x:0 y:0 |
5899 toX:0 y:0. |
5899 toX:0 y:0. |
5900 |
5900 |
5901 ^ form |
5901 ^ form |
5902 |
5902 |
5903 "Modified: 10.1.1997 / 17:53:23 / cg" |
5903 "Modified: 10.1.1997 / 17:53:23 / cg" |
5904 ! ! |
5904 ! ! |
6024 errorArray1 |
6024 errorArray1 |
6025 e t |
6025 e t |
6026 w "{Class: SmallInteger }" |
6026 w "{Class: SmallInteger }" |
6027 h "{Class: SmallInteger }" |
6027 h "{Class: SmallInteger }" |
6028 bitCnt "{Class: SmallInteger }" |
6028 bitCnt "{Class: SmallInteger }" |
6029 byte "{Class: SmallInteger }" |
6029 byte "{Class: SmallInteger }" |
6030 grey| |
6030 grey| |
6031 |
6031 |
6032 self depth > 12 ifTrue:[ |
6032 self depth > 12 ifTrue:[ |
6033 ^ self floydSteinbergDitheredMonochromeBits |
6033 ^ self floydSteinbergDitheredMonochromeBits |
6034 ]. |
6034 ]. |
6046 |
6046 |
6047 "/ fetch scaled brightness values outside of loop into a table; |
6047 "/ fetch scaled brightness values outside of loop into a table; |
6048 "/ use table-value in loop |
6048 "/ use table-value in loop |
6049 |
6049 |
6050 greyValues := self greyMapForRange:(255*1024). |
6050 greyValues := self greyMapForRange:(255*1024). |
6051 |
6051 |
6052 0 to:(h-1) do:[:y | |
6052 0 to:(h-1) do:[:y | |
6053 nextDst := dstIndex + bytesPerMonoRow. |
6053 nextDst := dstIndex + bytesPerMonoRow. |
6054 byte := 0. |
6054 byte := 0. |
6055 bitCnt := 8. |
6055 bitCnt := 8. |
6056 |
6056 |
6059 errorArray1 := t. |
6059 errorArray1 := t. |
6060 |
6060 |
6061 errorArray1 atAllPut:0. |
6061 errorArray1 atAllPut:0. |
6062 |
6062 |
6063 self valuesAtY:y from:0 to:(w-1) do:[:x :pixel | |
6063 self valuesAtY:y from:0 to:(w-1) do:[:x :pixel | |
6064 |eP "{Class: SmallInteger }" |
6064 |eP "{Class: SmallInteger }" |
6065 eD |
6065 eD |
6066 eI "{Class: SmallInteger }" |
6066 eI "{Class: SmallInteger }" |
6067 xE "{Class: SmallInteger }" |
6067 xE "{Class: SmallInteger }" |
6068 xN "{Class: SmallInteger }" | |
6068 xN "{Class: SmallInteger }" | |
6069 |
6069 |
6070 "/ get the colors grey value [0 .. 1] |
6070 "/ get the colors grey value [0 .. 1] |
6071 grey := greyValues at:(pixel + 1). |
6071 grey := greyValues at:(pixel + 1). |
6142 "Modified: 10.6.1996 / 13:16:33 / cg" |
6142 "Modified: 10.6.1996 / 13:16:33 / cg" |
6143 ! |
6143 ! |
6144 |
6144 |
6145 floydSteinbergDitheredDepth8BitsColors:colors |
6145 floydSteinbergDitheredDepth8BitsColors:colors |
6146 "return a floyd-steinberg dithered bitmap from the receiver picture, |
6146 "return a floyd-steinberg dithered bitmap from the receiver picture, |
6147 which must be a depth-8 image. |
6147 which must be a depth-8 image. |
6148 This method expects an array of colors to be used for dithering |
6148 This method expects an array of colors to be used for dithering |
6149 (which need not be a colorCubes colors)." |
6149 (which need not be a colorCubes colors)." |
6150 |
6150 |
6151 ^ self floydSteinbergDitheredDepth8BitsColors:colors map:nil |
6151 ^ self floydSteinbergDitheredDepth8BitsColors:colors map:nil |
6152 |
6152 |
6153 ! |
6153 ! |
6154 |
6154 |
6155 floydSteinbergDitheredDepth8BitsColors:colors map:aMapOrNil |
6155 floydSteinbergDitheredDepth8BitsColors:colors map:aMapOrNil |
6156 "return a floyd-steinberg dithered bitmap from the receiver picture, |
6156 "return a floyd-steinberg dithered bitmap from the receiver picture, |
6157 which must be a depth-24 image. |
6157 which must be a depth-24 image. |
6158 This method expects an array of colors to be used for dithering |
6158 This method expects an array of colors to be used for dithering |
6159 (which need not be a colorCubes colors)." |
6159 (which need not be a colorCubes colors)." |
6160 |
6160 |
6161 |pseudoBits |
6161 |pseudoBits |
6162 ditherRGBBytes ditherColors |
6162 ditherRGBBytes ditherColors |
6163 w "{Class: SmallInteger }" |
6163 w "{Class: SmallInteger }" |
6164 h "{Class: SmallInteger }" |
6164 h "{Class: SmallInteger }" |
6165 index "{Class: SmallInteger }" |
6165 index "{Class: SmallInteger }" |
6166 ditherIds failed lastColor qScramble |
6166 ditherIds failed lastColor qScramble |
6242 i := qScramble at:((r bitShift:-4) bitAnd:16r0F) + 1. |
6242 i := qScramble at:((r bitShift:-4) bitAnd:16r0F) + 1. |
6243 i := i + ((qScramble at:((g bitShift:-4) bitAnd:16r0F) + 1) bitShift:-1). |
6243 i := i + ((qScramble at:((g bitShift:-4) bitAnd:16r0F) + 1) bitShift:-1). |
6244 i := i + ((qScramble at:((b bitShift:-4) bitAnd:16r0F) + 1) bitShift:-2). |
6244 i := i + ((qScramble at:((b bitShift:-4) bitAnd:16r0F) + 1) bitShift:-2). |
6245 lookupPos := i. |
6245 lookupPos := i. |
6246 |
6246 |
6247 [index < lookupPos] whileTrue:[ |
6247 [index < lookupPos] whileTrue:[ |
6248 clrLookup at:(index+1) put:(clrPosition-1-1). |
6248 clrLookup at:(index+1) put:(clrPosition-1-1). |
6249 index := index + 1 |
6249 index := index + 1 |
6250 ] |
6250 ] |
6251 ]. |
6251 ]. |
6252 clrLookup from:index+1 to:4096 put:(ditherColors size - 1). |
6252 clrLookup from:index+1 to:4096 put:(ditherColors size - 1). |
6388 && (__wantG == __wG) |
6388 && (__wantG == __wG) |
6389 && (__wantB == __wB)) { |
6389 && (__wantB == __wB)) { |
6390 /* |
6390 /* |
6391 * same color again - reuse last bestMatch |
6391 * same color again - reuse last bestMatch |
6392 */ |
6392 */ |
6393 } else |
6393 } else |
6394 #endif |
6394 #endif |
6395 { |
6395 { |
6396 __wR = __wantR; |
6396 __wR = __wantR; |
6397 __wG = __wantG; |
6397 __wG = __wantG; |
6398 __wB = __wantB; |
6398 __wB = __wantB; |
6423 d = dp[0]; |
6423 d = dp[0]; |
6424 delta = (__wR - d) * RED_SCALE; |
6424 delta = (__wR - d) * RED_SCALE; |
6425 if (delta < 0) delta = -delta; |
6425 if (delta < 0) delta = -delta; |
6426 |
6426 |
6427 d = dp[1]; |
6427 d = dp[1]; |
6428 if (__wG > d) |
6428 if (__wG > d) |
6429 delta += (__wG - d) * GREEN_SCALE; |
6429 delta += (__wG - d) * GREEN_SCALE; |
6430 else |
6430 else |
6431 delta += (d - __wG) * GREEN_SCALE; |
6431 delta += (d - __wG) * GREEN_SCALE; |
6432 d = dp[2]; |
6432 d = dp[2]; |
6433 if (__wB > d) |
6433 if (__wB > d) |
6434 delta += (__wB - d) * BLUE_SCALE; |
6434 delta += (__wB - d) * BLUE_SCALE; |
6435 else |
6435 else |
6436 delta += (d - __wB) * BLUE_SCALE; |
6436 delta += (d - __wB) * BLUE_SCALE; |
6437 |
6437 |
6438 if (delta <= GOOD_DELTA) { |
6438 if (delta <= GOOD_DELTA) { |
6439 goto foundBest; |
6439 goto foundBest; |
6440 } |
6440 } |
6448 idx--; dp -= 3; |
6448 idx--; dp -= 3; |
6449 d = dp[0]; |
6449 d = dp[0]; |
6450 delta = (__wR - d) * RED_SCALE; |
6450 delta = (__wR - d) * RED_SCALE; |
6451 if (delta < 0) delta = -delta; |
6451 if (delta < 0) delta = -delta; |
6452 d = dp[1]; |
6452 d = dp[1]; |
6453 if (__wG > d) |
6453 if (__wG > d) |
6454 delta += (__wG - d) * GREEN_SCALE; |
6454 delta += (__wG - d) * GREEN_SCALE; |
6455 else |
6455 else |
6456 delta += (d - __wG) * GREEN_SCALE; |
6456 delta += (d - __wG) * GREEN_SCALE; |
6457 d = dp[2]; |
6457 d = dp[2]; |
6458 if (__wB > d) |
6458 if (__wB > d) |
6459 delta += (__wB - d) * BLUE_SCALE; |
6459 delta += (__wB - d) * BLUE_SCALE; |
6460 else |
6460 else |
6461 delta += (d - __wB) * BLUE_SCALE; |
6461 delta += (d - __wB) * BLUE_SCALE; |
6462 |
6462 |
6463 if (delta < minDelta) { |
6463 if (delta < minDelta) { |
6464 bestIdx = idx; |
6464 bestIdx = idx; |
6465 if (delta <= GOOD_DELTA) { |
6465 if (delta <= GOOD_DELTA) { |
6477 dp += 3; |
6477 dp += 3; |
6478 d = dp[0]; |
6478 d = dp[0]; |
6479 delta = (__wR - d) * RED_SCALE; |
6479 delta = (__wR - d) * RED_SCALE; |
6480 if (delta < 0) delta = -delta; |
6480 if (delta < 0) delta = -delta; |
6481 d = dp[1]; |
6481 d = dp[1]; |
6482 if (__wG > d) |
6482 if (__wG > d) |
6483 delta += (__wG - d) * GREEN_SCALE; |
6483 delta += (__wG - d) * GREEN_SCALE; |
6484 else |
6484 else |
6485 delta += (d - __wG) * GREEN_SCALE; |
6485 delta += (d - __wG) * GREEN_SCALE; |
6486 d = dp[2]; |
6486 d = dp[2]; |
6487 if (__wB > d) |
6487 if (__wB > d) |
6488 delta += (__wB - d) * BLUE_SCALE; |
6488 delta += (__wB - d) * BLUE_SCALE; |
6489 else |
6489 else |
6490 delta += (d - __wB) * BLUE_SCALE; |
6490 delta += (d - __wB) * BLUE_SCALE; |
6491 |
6491 |
6492 if (delta < minDelta) { |
6492 if (delta < minDelta) { |
6493 bestIdx = idx; |
6493 bestIdx = idx; |
6494 if (delta <= GOOD_DELTA) { |
6494 if (delta <= GOOD_DELTA) { |
6521 d = dp[0]; |
6521 d = dp[0]; |
6522 delta = (__wR - d) * RED_SCALE; |
6522 delta = (__wR - d) * RED_SCALE; |
6523 if (delta < 0) delta = -delta; |
6523 if (delta < 0) delta = -delta; |
6524 if (delta < minDelta) { |
6524 if (delta < minDelta) { |
6525 d = dp[1]; |
6525 d = dp[1]; |
6526 if (__wG > d) |
6526 if (__wG > d) |
6527 delta += (__wG - d) * GREEN_SCALE; |
6527 delta += (__wG - d) * GREEN_SCALE; |
6528 else |
6528 else |
6529 delta += (d - __wG) * GREEN_SCALE; |
6529 delta += (d - __wG) * GREEN_SCALE; |
6530 if (delta < minDelta) { |
6530 if (delta < minDelta) { |
6531 d = dp[2]; |
6531 d = dp[2]; |
6532 if (__wB > d) |
6532 if (__wB > d) |
6533 delta += (__wB - d) * BLUE_SCALE; |
6533 delta += (__wB - d) * BLUE_SCALE; |
6534 else |
6534 else |
6535 delta += (d - __wB) * BLUE_SCALE; |
6535 delta += (d - __wB) * BLUE_SCALE; |
6536 |
6536 |
6537 if (delta < minDelta) { |
6537 if (delta < minDelta) { |
6538 bestIdx = idx; |
6538 bestIdx = idx; |
6539 if (delta <= GOOD_DELTA) { |
6539 if (delta <= GOOD_DELTA) { |
6552 dR = dp[0]; |
6552 dR = dp[0]; |
6553 dG = dp[1]; |
6553 dG = dp[1]; |
6554 dB = dp[2]; |
6554 dB = dp[2]; |
6555 |
6555 |
6556 /* |
6556 /* |
6557 printf("want: %d/%d/%d (%d/%d/%d) got: %d/%d/%d\n", |
6557 console_printf("want: %d/%d/%d (%d/%d/%d) got: %d/%d/%d\n", |
6558 __wantR, __wantG, __wantB, |
6558 __wantR, __wantG, __wantB, |
6559 __wR, __wG, __wB, |
6559 __wR, __wG, __wB, |
6560 dR, dG, dB); |
6560 dR, dG, dB); |
6561 */ |
6561 */ |
6562 /* |
6562 /* |
6565 *dstP++ = idP[bestIdx]; |
6565 *dstP++ = idP[bestIdx]; |
6566 |
6566 |
6567 /* |
6567 /* |
6568 * the new error & distribute the error |
6568 * the new error & distribute the error |
6569 */ |
6569 */ |
6570 __eR = __wantR - dR; |
6570 __eR = __wantR - dR; |
6571 if (__eR) { |
6571 if (__eR) { |
6572 tR = __eR >> 4; /* 16th of error */ |
6572 tR = __eR >> 4; /* 16th of error */ |
6573 nR = eP[3] + (tR * 7);/* from accu: error for (x+1 / y) */ |
6573 nR = eP[3] + (tR * 7);/* from accu: error for (x+1 / y) */ |
6574 eP[0] = tR*5; /* 5/16th for (x / y+1) */ |
6574 eP[0] = tR*5; /* 5/16th for (x / y+1) */ |
6575 eP[-3] = tR*3; /* 3/16th for (x-1 / y+1) */ |
6575 eP[-3] = tR*3; /* 3/16th for (x-1 / y+1) */ |
6591 } else { |
6591 } else { |
6592 __eG = eP[4]; |
6592 __eG = eP[4]; |
6593 eP[1] = eP[-2] = eP[4] = 0; |
6593 eP[1] = eP[-2] = eP[4] = 0; |
6594 } |
6594 } |
6595 |
6595 |
6596 __eB = __wantB - dB; |
6596 __eB = __wantB - dB; |
6597 if (__eB) { |
6597 if (__eB) { |
6598 tB = __eB >> 4; |
6598 tB = __eB >> 4; |
6599 nB = eP[5] + (tB * 7); |
6599 nB = eP[5] + (tB * 7); |
6600 eP[2] = tB*5; |
6600 eP[2] = tB*5; |
6601 eP[-1] = tB*3; |
6601 eP[-1] = tB*3; |
6617 ]. |
6617 ]. |
6618 |
6618 |
6619 ^ pseudoBits |
6619 ^ pseudoBits |
6620 ! |
6620 ! |
6621 |
6621 |
6622 floydSteinbergDitheredDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
6622 floydSteinbergDitheredDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
6623 "return a floyd-steinberg dithered bitmap from the receiver picture, |
6623 "return a floyd-steinberg dithered bitmap from the receiver picture, |
6624 which must be a depth-8 image. |
6624 which must be a depth-8 image. |
6625 This is a special-cased dither method for 8-bit palette images being displayed on |
6625 This is a special-cased dither method for 8-bit palette images being displayed on |
6626 an 8-bit pseudoColor display, AND fixColor dithering is used. |
6626 an 8-bit pseudoColor display, AND fixColor dithering is used. |
6627 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
6627 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
6628 colors assigned to aDevice, such as the preallocated colors of the |
6628 colors assigned to aDevice, such as the preallocated colors of the |
6629 Color class. |
6629 Color class. |
6630 By passing the ditherColors as extra array, this method can |
6630 By passing the ditherColors as extra array, this method can |
6631 also be used to dither an 8bit image into a smaller number of colors, |
6631 also be used to dither an 8bit image into a smaller number of colors, |
6632 for example to create dithered Depth4Images from Depth8Images." |
6632 for example to create dithered Depth4Images from Depth8Images." |
6633 |
6633 |
6634 |pseudoBits |
6634 |pseudoBits |
6635 rgbBytes |
6635 rgbBytes |
6636 w "{Class: SmallInteger }" |
6636 w "{Class: SmallInteger }" |
6637 h "{Class: SmallInteger }" |
6637 h "{Class: SmallInteger }" |
6638 index "{Class: SmallInteger }" |
6638 index "{Class: SmallInteger }" |
6639 fixR "{Class: SmallInteger }" |
6639 fixR "{Class: SmallInteger }" |
6640 fixG "{Class: SmallInteger }" |
6640 fixG "{Class: SmallInteger }" |
6641 fixB "{Class: SmallInteger }" |
6641 fixB "{Class: SmallInteger }" |
6642 fixGfixB |
6642 fixGfixB |
6643 fixIds failed map lastColor |
6643 fixIds failed map lastColor |
6644 rgbIDX "{Class: SmallInteger }" |
6644 rgbIDX "{Class: SmallInteger }" |
6645 idxAndErrRBytes idxAndErrGBytes idxAndErrBBytes |
6645 idxAndErrRBytes idxAndErrGBytes idxAndErrBBytes |
6646 error clr| |
6646 error clr| |
6647 |
6647 |
6648 self depth ~~ 8 ifTrue:[^ nil]. |
6648 self depth ~~ 8 ifTrue:[^ nil]. |
6700 rgbIDX := (i * (fixR-1) + 128) // 255. "red index rounded" |
6700 rgbIDX := (i * (fixR-1) + 128) // 255. "red index rounded" |
6701 idxAndErrRBytes at:index put:(rgbIDX * fixGfixB). |
6701 idxAndErrRBytes at:index put:(rgbIDX * fixGfixB). |
6702 idxAndErrRBytes at:index+1 put:i - (rgbIDX * 255 // (fixR-1)) + 128. |
6702 idxAndErrRBytes at:index+1 put:i - (rgbIDX * 255 // (fixR-1)) + 128. |
6703 |
6703 |
6704 rgbIDX := (i * (fixG-1) + 128) // 255. "green index rounded" |
6704 rgbIDX := (i * (fixG-1) + 128) // 255. "green index rounded" |
6705 idxAndErrGBytes at:index put:(rgbIDX * fixB). |
6705 idxAndErrGBytes at:index put:(rgbIDX * fixB). |
6706 idxAndErrGBytes at:index+1 put:i - (rgbIDX * 255 // (fixG-1)) + 128. |
6706 idxAndErrGBytes at:index+1 put:i - (rgbIDX * 255 // (fixG-1)) + 128. |
6707 |
6707 |
6708 rgbIDX := (i * (fixB-1) + 128) // 255. "blue index rounded" |
6708 rgbIDX := (i * (fixB-1) + 128) // 255. "blue index rounded" |
6709 idxAndErrBBytes at:index put:(rgbIDX ). |
6709 idxAndErrBBytes at:index put:(rgbIDX ). |
6710 idxAndErrBBytes at:index+1 put:i - (rgbIDX * 255 // (fixB-1)) + 128. |
6710 idxAndErrBBytes at:index+1 put:i - (rgbIDX * 255 // (fixB-1)) + 128. |
6772 */ |
6772 */ |
6773 __want = rgbP[pix] + __eR; |
6773 __want = rgbP[pix] + __eR; |
6774 if (__want > 255) __want = 255; |
6774 if (__want > 255) __want = 255; |
6775 else if (__want < 0) __want = 0; |
6775 else if (__want < 0) __want = 0; |
6776 __want += __want; |
6776 __want += __want; |
6777 idx = __idxAndErrRBytes[__want]; |
6777 idx = __idxAndErrRBytes[__want]; |
6778 __eR = __idxAndErrRBytes[__want+1]; |
6778 __eR = __idxAndErrRBytes[__want+1]; |
6779 __eR -= 128; |
6779 __eR -= 128; |
6780 |
6780 |
6781 __want = rgbP[pix+1] + __eG; |
6781 __want = rgbP[pix+1] + __eG; |
6782 if (__want > 255) __want = 255; |
6782 if (__want > 255) __want = 255; |
6783 else if (__want < 0) __want = 0; |
6783 else if (__want < 0) __want = 0; |
6784 __want += __want; |
6784 __want += __want; |
6785 idx += __idxAndErrGBytes[__want]; |
6785 idx += __idxAndErrGBytes[__want]; |
6786 __eG = __idxAndErrGBytes[__want+1]; |
6786 __eG = __idxAndErrGBytes[__want+1]; |
6787 __eG -= 128; |
6787 __eG -= 128; |
6788 |
6788 |
6789 __want = rgbP[pix+2] + __eB; |
6789 __want = rgbP[pix+2] + __eB; |
6790 if (__want > 255) __want = 255; |
6790 if (__want > 255) __want = 255; |
6791 else if (__want < 0) __want = 0; |
6791 else if (__want < 0) __want = 0; |
6792 __want += __want; |
6792 __want += __want; |
6793 idx += __idxAndErrBBytes[__want]; |
6793 idx += __idxAndErrBBytes[__want]; |
6794 __eB = __idxAndErrBBytes[__want+1]; |
6794 __eB = __idxAndErrBBytes[__want+1]; |
6795 __eB -= 128; |
6795 __eB -= 128; |
6796 |
6796 |
6797 /* |
6797 /* |
6798 * store the corresponding dither colors colorId |
6798 * store the corresponding dither colors colorId |
6799 */ |
6799 */ |
6853 |
6853 |
6854 ! |
6854 ! |
6855 |
6855 |
6856 floydSteinbergDitheredGrayBitsDepth:depth |
6856 floydSteinbergDitheredGrayBitsDepth:depth |
6857 "return the bits for dithering a gray image from the image. |
6857 "return the bits for dithering a gray image from the image. |
6858 Works for any source depths / photometric, |
6858 Works for any source depths / photometric, |
6859 but possibly slow since each pixel is processed individually. |
6859 but possibly slow since each pixel is processed individually. |
6860 Redefined by some subclasses for more performance (D8Image/D24Image)" |
6860 Redefined by some subclasses for more performance (D8Image/D24Image)" |
6861 |
6861 |
6862 |dstIndex "{Class: SmallInteger }" |
6862 |dstIndex "{Class: SmallInteger }" |
6863 nextDst "{Class: SmallInteger }" |
6863 nextDst "{Class: SmallInteger }" |
6867 nextErrorArray |
6867 nextErrorArray |
6868 t |
6868 t |
6869 w "{Class: SmallInteger }" |
6869 w "{Class: SmallInteger }" |
6870 h "{Class: SmallInteger }" |
6870 h "{Class: SmallInteger }" |
6871 bitCnt "{Class: SmallInteger }" |
6871 bitCnt "{Class: SmallInteger }" |
6872 byte "{Class: SmallInteger }" |
6872 byte "{Class: SmallInteger }" |
6873 grey |
6873 grey |
6874 eR eRB eB eLB | |
6874 eR eRB eB eLB | |
6875 |
6875 |
6876 depth > 8 ifTrue:[ |
6876 depth > 8 ifTrue:[ |
6877 self error:'unimplemented conversion'. |
6877 self error:'unimplemented conversion'. |
6926 self valuesAtY:y from:0 to:(w-1) do:[:x :value | |
6926 self valuesAtY:y from:0 to:(w-1) do:[:x :value | |
6927 |e "{ Class: SmallInteger }" |
6927 |e "{ Class: SmallInteger }" |
6928 pixel "{ Class: SmallInteger }" |
6928 pixel "{ Class: SmallInteger }" |
6929 error "{ Class: SmallInteger }" |
6929 error "{ Class: SmallInteger }" |
6930 e16 "{ Class: SmallInteger }" |
6930 e16 "{ Class: SmallInteger }" |
6931 xE "{ Class: SmallInteger }" |
6931 xE "{ Class: SmallInteger }" |
6932 xN "{ Class: SmallInteger }" | |
6932 xN "{ Class: SmallInteger }" | |
6933 |
6933 |
6934 pixel := greyPixels at:(value + 1). |
6934 pixel := greyPixels at:(value + 1). |
6935 |
6935 |
6936 "/ adjust error |
6936 "/ adjust error |
6937 xE := x + 2. |
6937 xE := x + 2. |
6938 error := (greyErrors at:(value + 1)) + (errorArray at:xE). |
6938 error := (greyErrors at:(value + 1)) + (errorArray at:xE). |
6939 |
6939 |
6940 byte := byte bitShift:depth. |
6940 byte := byte bitShift:depth. |
6941 error > 512 "0.5" ifTrue:[ |
6941 error > 512 "0.5" ifTrue:[ |
6942 pixel := pixel + 1. |
6942 pixel := pixel + 1. |
6943 e := error - 1024 "1.0" |
6943 e := error - 1024 "1.0" |
6944 ] ifFalse:[ |
6944 ] ifFalse:[ |
6945 e := error |
6945 e := error |
6946 ]. |
6946 ]. |
6947 byte := byte bitOr:pixel. |
6947 byte := byte bitOr:pixel. |
6948 |
6948 |
6949 e ~= 0 ifTrue:[ |
6949 e ~= 0 ifTrue:[ |
6950 e16 := e // 16. |
6950 e16 := e // 16. |
7001 self colorsAtY:y from:0 to:(w-1) do:[:x :clr | |
7001 self colorsAtY:y from:0 to:(w-1) do:[:x :clr | |
7002 |e "{ Class: SmallInteger }" |
7002 |e "{ Class: SmallInteger }" |
7003 pixel "{ Class: SmallInteger }" |
7003 pixel "{ Class: SmallInteger }" |
7004 error "{ Class: SmallInteger }" |
7004 error "{ Class: SmallInteger }" |
7005 e16 "{ Class: SmallInteger }" |
7005 e16 "{ Class: SmallInteger }" |
7006 xE "{ Class: SmallInteger }" |
7006 xE "{ Class: SmallInteger }" |
7007 xN "{ Class: SmallInteger }" | |
7007 xN "{ Class: SmallInteger }" | |
7008 |
7008 |
7009 grey := (clr brightness * greyLevels). |
7009 grey := (clr brightness * greyLevels). |
7010 pixel := grey truncated. |
7010 pixel := grey truncated. |
7011 error := ((grey - pixel) * 1024) truncated. |
7011 error := ((grey - pixel) * 1024) truncated. |
7014 xE := x + 2. |
7014 xE := x + 2. |
7015 error := error + (errorArray at:xE). |
7015 error := error + (errorArray at:xE). |
7016 |
7016 |
7017 byte := byte bitShift:depth. |
7017 byte := byte bitShift:depth. |
7018 error > 512 "0.5" ifTrue:[ |
7018 error > 512 "0.5" ifTrue:[ |
7019 pixel := pixel + 1. |
7019 pixel := pixel + 1. |
7020 e := error - 1024 "1.0" |
7020 e := error - 1024 "1.0" |
7021 ] ifFalse:[ |
7021 ] ifFalse:[ |
7022 e := error |
7022 e := error |
7023 ]. |
7023 ]. |
7024 |
7024 |
7025 byte := byte bitOr:pixel. |
7025 byte := byte bitOr:pixel. |
7026 |
7026 |
7027 e ~= 0 ifTrue:[ |
7027 e ~= 0 ifTrue:[ |
7073 "Modified: 11.6.1996 / 00:13:38 / cg" |
7073 "Modified: 11.6.1996 / 00:13:38 / cg" |
7074 ! |
7074 ! |
7075 |
7075 |
7076 floydSteinbergDitheredMonochromeBits |
7076 floydSteinbergDitheredMonochromeBits |
7077 "return the bitmap for a dithered monochrome bitmap from the image. |
7077 "return the bitmap for a dithered monochrome bitmap from the image. |
7078 Works for any source depths / photometric, |
7078 Works for any source depths / photometric, |
7079 but very very slow since each pixel is processed individually. |
7079 but very very slow since each pixel is processed individually. |
7080 Redefined by some subclasses for more performance (D8Image)" |
7080 Redefined by some subclasses for more performance (D8Image)" |
7081 |
7081 |
7082 |dstIndex "{Class: SmallInteger }" |
7082 |dstIndex "{Class: SmallInteger }" |
7083 nextDst "{Class: SmallInteger }" |
7083 nextDst "{Class: SmallInteger }" |
7087 nextErrorArray |
7087 nextErrorArray |
7088 e eD t |
7088 e eD t |
7089 w "{Class: SmallInteger }" |
7089 w "{Class: SmallInteger }" |
7090 h "{Class: SmallInteger }" |
7090 h "{Class: SmallInteger }" |
7091 bitCnt "{Class: SmallInteger }" |
7091 bitCnt "{Class: SmallInteger }" |
7092 byte "{Class: SmallInteger }" |
7092 byte "{Class: SmallInteger }" |
7093 grey |
7093 grey |
7094 eR eRB eB eLB | |
7094 eR eRB eB eLB | |
7095 |
7095 |
7096 w := width. |
7096 w := width. |
7097 h := height. |
7097 h := height. |
7098 |
7098 |
7134 int __eR, __eB, __eRB, __eLB, __eI; |
7134 int __eR, __eB, __eRB, __eLB, __eI; |
7135 int __bitCnt = __intVal(bitCnt); |
7135 int __bitCnt = __intVal(bitCnt); |
7136 |
7136 |
7137 __grey = __intVal(__ArrayInstPtr(greyValues)->a_element[__intVal(pixel)]); |
7137 __grey = __intVal(__ArrayInstPtr(greyValues)->a_element[__intVal(pixel)]); |
7138 __grey += __intVal(__errorArray[__x+1]); |
7138 __grey += __intVal(__errorArray[__x+1]); |
7139 |
7139 |
7140 __byte <<= 1; |
7140 __byte <<= 1; |
7141 if (__grey > 127*1024) { |
7141 if (__grey > 127*1024) { |
7142 __e = __grey - (255*1024); |
7142 __e = __grey - (255*1024); |
7143 __byte |= 1; |
7143 __byte |= 1; |
7144 } else { |
7144 } else { |
7145 __e = __grey; |
7145 __e = __grey; |
7146 } |
7146 } |
7147 if (__e) { |
7147 if (__e) { |
7148 __eI = __e >> 4; |
7148 __eI = __e >> 4; |
7149 __eR = __eI * 7; |
7149 __eR = __eI * 7; |
7150 __eRB = __eI * 1; |
7150 __eRB = __eI * 1; |
7151 __eB = __eI * 5; |
7151 __eB = __eI * 5; |
7152 __eLB = __e - __eR - __eRB - __eB; |
7152 __eLB = __e - __eR - __eRB - __eB; |
7153 __errorArray[__x+2] = __MKSMALLINT(__intVal(__errorArray[__x+2]) + __eR); |
7153 __errorArray[__x+2] = __MKSMALLINT(__intVal(__errorArray[__x+2]) + __eR); |
7154 __nextErrorArray[__x+2] = __MKSMALLINT(__intVal(__nextErrorArray[__x+2]) + __eRB); |
7154 __nextErrorArray[__x+2] = __MKSMALLINT(__intVal(__nextErrorArray[__x+2]) + __eRB); |
7155 __nextErrorArray[__x+1] = __MKSMALLINT(__intVal(__nextErrorArray[__x+1]) + __eB); |
7155 __nextErrorArray[__x+1] = __MKSMALLINT(__intVal(__nextErrorArray[__x+1]) + __eB); |
7156 __nextErrorArray[__x ] = __MKSMALLINT(__intVal(__nextErrorArray[__x ]) + __eLB); |
7156 __nextErrorArray[__x ] = __MKSMALLINT(__intVal(__nextErrorArray[__x ]) + __eLB); |
7167 } |
7167 } |
7168 byte = __MKSMALLINT(__byte); |
7168 byte = __MKSMALLINT(__byte); |
7169 bitCnt = __MKSMALLINT(__bitCnt); |
7169 bitCnt = __MKSMALLINT(__bitCnt); |
7170 %}. |
7170 %}. |
7171 |
7171 |
7172 "/ |eI "{ Class: SmallInteger }" |
7172 "/ |eI "{ Class: SmallInteger }" |
7173 "/ xE "{ Class: SmallInteger }" |
7173 "/ xE "{ Class: SmallInteger }" |
7174 "/ xN "{ Class: SmallInteger }" | |
7174 "/ xN "{ Class: SmallInteger }" | |
7175 "/ |
7175 "/ |
7176 "/ "/ get the colors grey value [0 .. 1] |
7176 "/ "/ get the colors grey value [0 .. 1] |
7177 "/ grey := greyValues at:(pixel + 1). |
7177 "/ grey := greyValues at:(pixel + 1). |
7178 "/ |
7178 "/ |
7241 nextErrorArray := t. |
7241 nextErrorArray := t. |
7242 |
7242 |
7243 nextErrorArray atAllPut:0. |
7243 nextErrorArray atAllPut:0. |
7244 |
7244 |
7245 self colorsAtY:y from:0 to:(w-1) do:[:x :clr | |
7245 self colorsAtY:y from:0 to:(w-1) do:[:x :clr | |
7246 |eI "{ Class: SmallInteger }" |
7246 |eI "{ Class: SmallInteger }" |
7247 xE "{ Class: SmallInteger }" |
7247 xE "{ Class: SmallInteger }" |
7248 xN "{ Class: SmallInteger }" | |
7248 xN "{ Class: SmallInteger }" | |
7249 |
7249 |
7250 "/ get the colors grey value [0 .. 1] |
7250 "/ get the colors grey value [0 .. 1] |
7251 grey := (clr brightness * 255). |
7251 grey := (clr brightness * 255). |
7252 |
7252 |
7310 |
7310 |
7311 "Created: 8.6.1996 / 16:39:46 / cg" |
7311 "Created: 8.6.1996 / 16:39:46 / cg" |
7312 "Modified: 10.6.1996 / 15:12:11 / cg" |
7312 "Modified: 10.6.1996 / 15:12:11 / cg" |
7313 ! |
7313 ! |
7314 |
7314 |
7315 nearestPaintDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
7315 nearestPaintDepth8BitsColors:fixColors nRed:nRed nGreen:nGreen nBlue:nBlue |
7316 "return a nearest paint bitmap from the receiver picture, |
7316 "return a nearest paint bitmap from the receiver picture, |
7317 which must be a depth-8 image. |
7317 which must be a depth-8 image. |
7318 This is a special-cased dither method for 8-bit palette images being displayed on |
7318 This is a special-cased dither method for 8-bit palette images being displayed on |
7319 an 8-bit pseudoColor display, AND fixColor dithering is used. |
7319 an 8-bit pseudoColor display, AND fixColor dithering is used. |
7320 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
7320 Use the colors in the fixColors array, which must be fixR x fixG x fixB |
7321 colors assigned to aDevice, such as the preallocated colors of the |
7321 colors assigned to aDevice, such as the preallocated colors of the |
7322 Color class." |
7322 Color class." |
7323 |
7323 |
7324 |pseudoBits |
7324 |pseudoBits |
7325 fixR "{Class: SmallInteger }" |
7325 fixR "{Class: SmallInteger }" |
7326 fixG "{Class: SmallInteger }" |
7326 fixG "{Class: SmallInteger }" |
7327 fixB "{Class: SmallInteger }" |
7327 fixB "{Class: SmallInteger }" |
7328 fixGfixB |
7328 fixGfixB |
7329 r "{Class: SmallInteger }" |
7329 r "{Class: SmallInteger }" |
7330 g "{Class: SmallInteger }" |
7330 g "{Class: SmallInteger }" |
7331 b "{Class: SmallInteger }" |
7331 b "{Class: SmallInteger }" |
7332 idx "{Class: SmallInteger }" |
7332 idx "{Class: SmallInteger }" |
7333 idMap lastColor |
7333 idMap lastColor |
7334 clr| |
7334 clr| |
7335 |
7335 |
7336 self depth ~~ 8 ifTrue:[^ nil]. |
7336 self depth ~~ 8 ifTrue:[^ nil]. |
7337 |
7337 |
7338 photometric == #palette ifTrue:[ |
7338 photometric == #palette ifTrue:[ |
7396 "Modified: 18.6.1996 / 09:18:09 / cg" |
7396 "Modified: 18.6.1996 / 09:18:09 / cg" |
7397 ! |
7397 ! |
7398 |
7398 |
7399 nfloydSteinbergDitheredDepth8BitsColors:colors |
7399 nfloydSteinbergDitheredDepth8BitsColors:colors |
7400 "return a floyd-steinberg dithered bitmap from the receiver picture, |
7400 "return a floyd-steinberg dithered bitmap from the receiver picture, |
7401 which must be a depth-8 image. |
7401 which must be a depth-8 image. |
7402 This method expects an array of colors to be used for dithering |
7402 This method expects an array of colors to be used for dithering |
7403 (which need not be a colorCubes colors)." |
7403 (which need not be a colorCubes colors)." |
7404 |
7404 |
7405 |pseudoBits |
7405 |pseudoBits |
7406 rgbBytes |
7406 rgbBytes |
7407 ditherRGBBytes ditherColors |
7407 ditherRGBBytes ditherColors |
7408 w "{Class: SmallInteger }" |
7408 w "{Class: SmallInteger }" |
7409 h "{Class: SmallInteger }" |
7409 h "{Class: SmallInteger }" |
7410 index "{Class: SmallInteger }" |
7410 index "{Class: SmallInteger }" |
7411 numR "{Class: SmallInteger }" |
7411 numR "{Class: SmallInteger }" |
7427 dG "{Class: SmallInteger }" |
7427 dG "{Class: SmallInteger }" |
7428 dB "{Class: SmallInteger }" |
7428 dB "{Class: SmallInteger }" |
7429 iR "{Class: SmallInteger }" |
7429 iR "{Class: SmallInteger }" |
7430 iRG "{Class: SmallInteger }" |
7430 iRG "{Class: SmallInteger }" |
7431 iRGB "{Class: SmallInteger }" |
7431 iRGB "{Class: SmallInteger }" |
7432 clr |
7432 clr |
7433 rI "{Class: SmallInteger }" |
7433 rI "{Class: SmallInteger }" |
7434 gI "{Class: SmallInteger }" |
7434 gI "{Class: SmallInteger }" |
7435 bI "{Class: SmallInteger }" |
7435 bI "{Class: SmallInteger }" |
7436 maxIDX "{Class: SmallInteger }" |
7436 maxIDX "{Class: SmallInteger }" |
7437 subCubeColorCollection |
7437 subCubeColorCollection |
7438 error |
7438 error |
7439 dl "{Class: SmallInteger }"| |
7439 dl "{Class: SmallInteger }"| |
7440 |
7440 |
7441 self depth ~~ 8 ifTrue:[^ nil]. |
7441 self depth ~~ 8 ifTrue:[^ nil]. |
7442 |
7442 |
7443 "/ |
7443 "/ |
7535 "/ cube keysAndValuesDo:[:i :indices | |
7535 "/ cube keysAndValuesDo:[:i :indices | |
7536 "/ indices notNil ifTrue:[ |
7536 "/ indices notNil ifTrue:[ |
7537 "/ nCube at:i put:(indices asByteArray) |
7537 "/ nCube at:i put:(indices asByteArray) |
7538 "/ ] ifFalse:[ |
7538 "/ ] ifFalse:[ |
7539 "/ "/ find nearest color |
7539 "/ "/ find nearest color |
7540 "/ |
7540 "/ |
7541 "/ dl := 1. |
7541 "/ dl := 1. |
7542 "/ [dl < maxBits] whileTrue:[ |
7542 "/ [dl < maxBits] whileTrue:[ |
7543 "/ dR := dl negated. |
7543 "/ dR := dl negated. |
7544 "/ [dR <= dl] whileTrue:[ |
7544 "/ [dR <= dl] whileTrue:[ |
7545 "/ iR := i + (dR * shR). |
7545 "/ iR := i + (dR * shR). |
7546 "/ (iR > 0 and:[iR < maxIDX]) ifTrue:[ |
7546 "/ (iR > 0 and:[iR < maxIDX]) ifTrue:[ |
7547 "/ dG := dl negated. |
7547 "/ dG := dl negated. |
7548 "/ [dG < dl] whileTrue:[ |
7548 "/ [dG < dl] whileTrue:[ |
7549 "/ iRG := iR + (dG * shG). |
7549 "/ iRG := iR + (dG * shG). |
7550 "/ (iRG > 0 and:[iRG < maxIDX]) ifTrue:[ |
7550 "/ (iRG > 0 and:[iRG < maxIDX]) ifTrue:[ |
7551 "/ dB := dl negated. |
7551 "/ dB := dl negated. |
7570 "/ ] |
7570 "/ ] |
7571 "/ ]. |
7571 "/ ]. |
7572 "/self halt. |
7572 "/self halt. |
7573 |
7573 |
7574 "/ now, cube contains collections of colors which are |
7574 "/ now, cube contains collections of colors which are |
7575 "/ positioned in a subCube; quickly accessed by a lookup |
7575 "/ positioned in a subCube; quickly accessed by a lookup |
7576 |
7576 |
7577 pseudoBits := ByteArray uninitializedNew:(width * height). |
7577 pseudoBits := ByteArray uninitializedNew:(width * height). |
7578 |
7578 |
7579 w := width. |
7579 w := width. |
7580 h := height. |
7580 h := height. |
7648 int tR, tG, tB; |
7648 int tR, tG, tB; |
7649 int nR, nG, nB; |
7649 int nR, nG, nB; |
7650 int __dR, __dG, __dB; |
7650 int __dR, __dG, __dB; |
7651 int minDelta, bestIdx; |
7651 int minDelta, bestIdx; |
7652 int __iR, __iG, __iB; |
7652 int __iR, __iG, __iB; |
7653 int cR, cG, cB; |
7653 int cR, cG, cB; |
7654 int delta; |
7654 int delta; |
7655 OBJ subCubeColors; |
7655 OBJ subCubeColors; |
7656 |
7656 |
7657 pix = *srcP++; |
7657 pix = *srcP++; |
7658 |
7658 |
7806 #endif |
7806 #endif |
7807 } else { |
7807 } else { |
7808 #ifdef REMEMBER_SEARCH |
7808 #ifdef REMEMBER_SEARCH |
7809 if (__isSmallInteger(subCubeColors)) { |
7809 if (__isSmallInteger(subCubeColors)) { |
7810 bestIdx = __intVal(subCubeColors); |
7810 bestIdx = __intVal(subCubeColors); |
7811 } else |
7811 } else |
7812 #endif |
7812 #endif |
7813 { |
7813 { |
7814 bestIdx = __ByteArrayInstPtr(subCubeColors)->ba_element[0]; |
7814 bestIdx = __ByteArrayInstPtr(subCubeColors)->ba_element[0]; |
7815 } |
7815 } |
7816 } |
7816 } |
7817 |
7817 |
7818 /* |
7818 /* |
7819 * ok, now, we have found a collection of nearby |
7819 * ok, now, we have found a collection of nearby |
7820 * colors in subCubeColors. |
7820 * colors in subCubeColors. |
7821 * |
7821 * |
7822 * since the error is at most 1/16 (i.e. roughly 6%), |
7822 * since the error is at most 1/16 (i.e. roughly 6%), |
7841 __dB = dp[2]; |
7841 __dB = dp[2]; |
7842 } |
7842 } |
7843 #endif |
7843 #endif |
7844 |
7844 |
7845 /* |
7845 /* |
7846 printf("want: %d/%d/%d (%d/%d/%d) got: %d/%d/%d\n", |
7846 console_printf("want: %d/%d/%d (%d/%d/%d) got: %d/%d/%d\n", |
7847 __wantR, __wantG, __wantB, |
7847 __wantR, __wantG, __wantB, |
7848 __wR, __wG, __wB, |
7848 __wR, __wG, __wB, |
7849 __dR, __dG, __dB); |
7849 __dR, __dG, __dB); |
7850 */ |
7850 */ |
7851 /* |
7851 /* |
7855 |
7855 |
7856 #ifndef NO_FLOYD_STEINBERG |
7856 #ifndef NO_FLOYD_STEINBERG |
7857 /* |
7857 /* |
7858 * the new error & distribute the error |
7858 * the new error & distribute the error |
7859 */ |
7859 */ |
7860 __eR = __wantR - __dR; |
7860 __eR = __wantR - __dR; |
7861 if (__eR) { |
7861 if (__eR) { |
7862 tR = __eR >> 4; /* 16th of error */ |
7862 tR = __eR >> 4; /* 16th of error */ |
7863 nR = eP[3] + (tR * 7);/* from accu: error for (x+1 / y) */ |
7863 nR = eP[3] + (tR * 7);/* from accu: error for (x+1 / y) */ |
7864 eP[0] = tR*5; /* 5/16th for (x / y+1) */ |
7864 eP[0] = tR*5; /* 5/16th for (x / y+1) */ |
7865 eP[-3] = tR*3; /* 3/16th for (x-1 / y+1) */ |
7865 eP[-3] = tR*3; /* 3/16th for (x-1 / y+1) */ |
7881 } else { |
7881 } else { |
7882 __eG = eP[4]; |
7882 __eG = eP[4]; |
7883 eP[1] = eP[-2] = eP[4] = 0; |
7883 eP[1] = eP[-2] = eP[4] = 0; |
7884 } |
7884 } |
7885 |
7885 |
7886 __eB = __wantB - __dB; |
7886 __eB = __wantB - __dB; |
7887 if (__eB) { |
7887 if (__eB) { |
7888 tB = __eB >> 4; |
7888 tB = __eB >> 4; |
7889 nB = eP[5] + (tB * 7); |
7889 nB = eP[5] + (tB * 7); |
7890 eP[2] = tB*5; |
7890 eP[2] = tB*5; |
7891 eP[-1] = tB*3; |
7891 eP[-1] = tB*3; |
7941 ! |
7941 ! |
7942 |
7942 |
7943 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth |
7943 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth |
7944 "return the bitmap for a dithered depth-bitmap from the image; |
7944 "return the bitmap for a dithered depth-bitmap from the image; |
7945 with a constant ditherMatrix, this can be used for thresholding. |
7945 with a constant ditherMatrix, this can be used for thresholding. |
7946 Works for any source depths / photometric, |
7946 Works for any source depths / photometric, |
7947 but very very slow since each pixel is processed individually. |
7947 but very very slow since each pixel is processed individually. |
7948 Redefined by some subclasses for more performance (D8Image)" |
7948 Redefined by some subclasses for more performance (D8Image)" |
7949 |
7949 |
7950 |dH nDither |
7950 |dH nDither |
7951 greyLevels greyValues greyPixels greyErrors |
7951 greyLevels greyValues greyPixels greyErrors |
7952 dstIndex "{Class: SmallInteger }" |
7952 dstIndex "{Class: SmallInteger }" |
7953 nextDst |
7953 nextDst |
7954 bytesPerOutRow "{Class: SmallInteger }" |
7954 bytesPerOutRow "{Class: SmallInteger }" |
7955 pixelsPerByte "{Class: SmallInteger }" |
7955 pixelsPerByte "{Class: SmallInteger }" |
7956 outBits |
7956 outBits |
7957 w "{Class: SmallInteger }" |
7957 w "{Class: SmallInteger }" |
7958 h "{Class: SmallInteger }" |
7958 h "{Class: SmallInteger }" |
8015 |
8015 |
8016 __pixel = __greyPixels[__value]; |
8016 __pixel = __greyPixels[__value]; |
8017 __grey = __greyErrors[__value]; |
8017 __grey = __greyErrors[__value]; |
8018 |
8018 |
8019 __dT = __ByteArrayInstPtr(ditherMatrix) |
8019 __dT = __ByteArrayInstPtr(ditherMatrix) |
8020 ->ba_element[__intVal(x) % __dW |
8020 ->ba_element[__intVal(x) % __dW |
8021 + (__intVal(y) % __intVal(dH)) * __dW]; |
8021 + (__intVal(y) % __intVal(dH)) * __dW]; |
8022 |
8022 |
8023 if (__grey > __dT) { |
8023 if (__grey > __dT) { |
8024 __pixel++; |
8024 __pixel++; |
8025 } |
8025 } |
8054 byte := 0. |
8054 byte := 0. |
8055 bitCnt := 8. |
8055 bitCnt := 8. |
8056 |
8056 |
8057 "/ this is the representaion independent (but slow) |
8057 "/ this is the representaion independent (but slow) |
8058 "/ inner loop - it extracts colors from the receiver |
8058 "/ inner loop - it extracts colors from the receiver |
8059 |
8059 |
8060 self colorsAtY:y from:0 to:(w-1) do:[:x :clr | |
8060 self colorsAtY:y from:0 to:(w-1) do:[:x :clr | |
8061 |dstClr grey dT pixel| |
8061 |dstClr grey dT pixel| |
8062 |
8062 |
8063 "/ get the colors grey value [0 .. 1] |
8063 "/ get the colors grey value [0 .. 1] |
8064 grey := clr brightness. |
8064 grey := clr brightness. |
8065 |
8065 |
8066 "/ remap into [0 .. greyLevels-1] |
8066 "/ remap into [0 .. greyLevels-1] |
8067 grey := grey * (greyLevels-1). |
8067 grey := grey * (greyLevels-1). |
8068 |
8068 |
8069 "/ get threshold pixel [0 .. greyLevels-1] |
8069 "/ get threshold pixel [0 .. greyLevels-1] |
8070 |
8070 |
8071 pixel := grey truncated. |
8071 pixel := grey truncated. |
8072 |
8072 |
8073 "/ compute the error [0..1] |
8073 "/ compute the error [0..1] |
8074 grey := grey - pixel. |
8074 grey := grey - pixel. |
8075 |
8075 |
8076 "/ map into dither space [0 .. nDither] |
8076 "/ map into dither space [0 .. nDither] |
8083 int __dstIdx; |
8083 int __dstIdx; |
8084 int __pixel; |
8084 int __pixel; |
8085 int __bitCnt = __intVal(bitCnt); |
8085 int __bitCnt = __intVal(bitCnt); |
8086 |
8086 |
8087 __dT = __ByteArrayInstPtr(ditherMatrix) |
8087 __dT = __ByteArrayInstPtr(ditherMatrix) |
8088 ->ba_element[__intVal(x) % __dW |
8088 ->ba_element[__intVal(x) % __dW |
8089 + (__intVal(y) % __intVal(dH)) * __dW]; |
8089 + (__intVal(y) % __intVal(dH)) * __dW]; |
8090 |
8090 |
8091 __pixel = __intVal(pixel); |
8091 __pixel = __intVal(pixel); |
8092 |
8092 |
8093 if (__intVal(grey) > __dT) { |
8093 if (__intVal(grey) > __dT) { |
8094 __pixel++; |
8094 __pixel++; |
8095 } |
8095 } |
8096 __byte = (__byte << __intVal(depth)) | __pixel; |
8096 __byte = (__byte << __intVal(depth)) | __pixel; |
8097 |
8097 |
8098 __bitCnt = __bitCnt - __intVal(depth); |
8098 __bitCnt = __bitCnt - __intVal(depth); |
8099 if (__bitCnt == 0) { |
8099 if (__bitCnt == 0) { |
8100 __dstIdx = __intVal(dstIndex); |
8100 __dstIdx = __intVal(dstIndex); |
8101 __ByteArrayInstPtr(outBits)->ba_element[__dstIdx-1] = __byte; |
8101 __ByteArrayInstPtr(outBits)->ba_element[__dstIdx-1] = __byte; |
8102 __dstIdx = __dstIdx + 1; |
8102 __dstIdx = __dstIdx + 1; |
8132 ! |
8132 ! |
8133 |
8133 |
8134 orderedDitheredMonochromeBitsWithDitherMatrix:ditherMatrix ditherWidth:dW |
8134 orderedDitheredMonochromeBitsWithDitherMatrix:ditherMatrix ditherWidth:dW |
8135 "return the bitmap for a dithered monochrome bitmap from the image; |
8135 "return the bitmap for a dithered monochrome bitmap from the image; |
8136 with a constant ditherMatrix, this can be used for thresholding. |
8136 with a constant ditherMatrix, this can be used for thresholding. |
8137 Works for any source depths / photometric, |
8137 Works for any source depths / photometric, |
8138 but very very slow since each pixel is processed individually. |
8138 but very very slow since each pixel is processed individually. |
8139 Redefined by some subclasses for more performance (D8Image)" |
8139 Redefined by some subclasses for more performance (D8Image)" |
8140 |
8140 |
8141 |dH nDither |
8141 |dH nDither |
8142 greyValues |
8142 greyValues |
8143 dstIndex "{Class: SmallInteger }" |
8143 dstIndex "{Class: SmallInteger }" |
8144 nextDst "{Class: SmallInteger }" |
8144 nextDst "{Class: SmallInteger }" |
8145 bytesPerMonoRow "{Class: SmallInteger }" |
8145 bytesPerMonoRow "{Class: SmallInteger }" |
8146 monoBits |
8146 monoBits |
8181 unsigned char *__greyValues = __ByteArrayInstPtr(greyValues)->ba_element; |
8181 unsigned char *__greyValues = __ByteArrayInstPtr(greyValues)->ba_element; |
8182 |
8182 |
8183 __grey = __greyValues[__intVal(value)]; |
8183 __grey = __greyValues[__intVal(value)]; |
8184 |
8184 |
8185 __dT = __ByteArrayInstPtr(ditherMatrix) |
8185 __dT = __ByteArrayInstPtr(ditherMatrix) |
8186 ->ba_element[__intVal(x) % __dW |
8186 ->ba_element[__intVal(x) % __dW |
8187 + (__intVal(y) % __intVal(dH)) * __dW]; |
8187 + (__intVal(y) % __intVal(dH)) * __dW]; |
8188 |
8188 |
8189 __byte = __byte << 1; |
8189 __byte = __byte << 1; |
8190 if (__grey > __dT) { |
8190 if (__grey > __dT) { |
8191 __byte = __byte | 1; /* white */ |
8191 __byte = __byte | 1; /* white */ |
8232 int __dT; |
8232 int __dT; |
8233 int __dstIdx; |
8233 int __dstIdx; |
8234 int __bitCnt = __intVal(bitCnt); |
8234 int __bitCnt = __intVal(bitCnt); |
8235 |
8235 |
8236 __dT = __ByteArrayInstPtr(ditherMatrix) |
8236 __dT = __ByteArrayInstPtr(ditherMatrix) |
8237 ->ba_element[__intVal(x) % __dW |
8237 ->ba_element[__intVal(x) % __dW |
8238 + (__intVal(y) % __intVal(dH)) * __dW]; |
8238 + (__intVal(y) % __intVal(dH)) * __dW]; |
8239 |
8239 |
8240 __byte = __byte << 1; |
8240 __byte = __byte << 1; |
8241 if (__intVal(grey) > __dT) { |
8241 if (__intVal(grey) > __dT) { |
8242 __byte = __byte | 1; /* white */ |
8242 __byte = __byte | 1; /* white */ |
8254 bitCnt = __MKSMALLINT(__bitCnt); |
8254 bitCnt = __MKSMALLINT(__bitCnt); |
8255 %}. |
8255 %}. |
8256 0 |
8256 0 |
8257 |
8257 |
8258 "/ dT := ditherMatrix at:(x \\ dW) + (y \\ dH * dW) + 1. |
8258 "/ dT := ditherMatrix at:(x \\ dW) + (y \\ dH * dW) + 1. |
8259 "/ |
8259 "/ |
8260 "/ byte := byte bitShift:1. |
8260 "/ byte := byte bitShift:1. |
8261 "/ grey < dT ifTrue:[ |
8261 "/ grey < dT ifTrue:[ |
8262 "/ byte := byte bitOr:1. |
8262 "/ byte := byte bitOr:1. |
8263 "/ ]. |
8263 "/ ]. |
8264 "/ bitCnt := bitCnt - 1. |
8264 "/ bitCnt := bitCnt - 1. |
8292 errorArray1 errorArray2 errorArray3 |
8292 errorArray1 errorArray2 errorArray3 |
8293 e t |
8293 e t |
8294 w "{Class: SmallInteger }" |
8294 w "{Class: SmallInteger }" |
8295 h "{Class: SmallInteger }" |
8295 h "{Class: SmallInteger }" |
8296 bitCnt "{Class: SmallInteger }" |
8296 bitCnt "{Class: SmallInteger }" |
8297 byte "{Class: SmallInteger }" |
8297 byte "{Class: SmallInteger }" |
8298 grey |
8298 grey |
8299 xE "{Class: SmallInteger }" | |
8299 xE "{Class: SmallInteger }" | |
8300 |
8300 |
8301 self depth > 12 ifTrue:[ |
8301 self depth > 12 ifTrue:[ |
8302 ^ self floydSteinbergDitheredMonochromeBits |
8302 ^ self floydSteinbergDitheredMonochromeBits |
8317 |
8317 |
8318 "/ fetch scaled brightness values outside of loop into a table; |
8318 "/ fetch scaled brightness values outside of loop into a table; |
8319 "/ use table-value in loop |
8319 "/ use table-value in loop |
8320 |
8320 |
8321 greyValues := self greyMapForRange:(255 * 1024). |
8321 greyValues := self greyMapForRange:(255 * 1024). |
8322 |
8322 |
8323 0 to:(h-1) do:[:y | |
8323 0 to:(h-1) do:[:y | |
8324 nextDst := dstIndex + bytesPerMonoRow. |
8324 nextDst := dstIndex + bytesPerMonoRow. |
8325 byte := 0. |
8325 byte := 0. |
8326 bitCnt := 8. |
8326 bitCnt := 8. |
8327 |
8327 |
8427 "draw a rectangle with some pixel value. |
8427 "draw a rectangle with some pixel value. |
8428 By using #atImageAndMask:put: it also works on images with mono masks." |
8428 By using #atImageAndMask:put: it also works on images with mono masks." |
8429 |
8429 |
8430 |xI "{ Class: SmallInteger }" |
8430 |xI "{ Class: SmallInteger }" |
8431 yI "{ Class: SmallInteger }" |
8431 yI "{ Class: SmallInteger }" |
8432 wI "{ Class: SmallInteger }" |
8432 wI "{ Class: SmallInteger }" |
8433 hI "{ Class: SmallInteger }"| |
8433 hI "{ Class: SmallInteger }"| |
8434 |
8434 |
8435 xI := aRectangle left. |
8435 xI := aRectangle left. |
8436 yI := aRectangle top. |
8436 yI := aRectangle top. |
8437 wI := aRectangle width. |
8437 wI := aRectangle width. |
8453 "draw a rectangle with some pixel value. |
8453 "draw a rectangle with some pixel value. |
8454 By using #atImageAndMask:put: it also works on images with mono masks." |
8454 By using #atImageAndMask:put: it also works on images with mono masks." |
8455 |
8455 |
8456 |xI "{ Class: SmallInteger }" |
8456 |xI "{ Class: SmallInteger }" |
8457 yI "{ Class: SmallInteger }" |
8457 yI "{ Class: SmallInteger }" |
8458 wI "{ Class: SmallInteger }" |
8458 wI "{ Class: SmallInteger }" |
8459 hI "{ Class: SmallInteger }"| |
8459 hI "{ Class: SmallInteger }"| |
8460 |
8460 |
8461 xI := aRectangle left. |
8461 xI := aRectangle left. |
8462 yI := aRectangle top. |
8462 yI := aRectangle top. |
8463 wI := aRectangle width. |
8463 wI := aRectangle width. |
8482 "fill a rectangular area with some pixel value. |
8482 "fill a rectangular area with some pixel value. |
8483 May be redefined in concrete subclasses for more performance, if req'd." |
8483 May be redefined in concrete subclasses for more performance, if req'd." |
8484 |
8484 |
8485 |xI "{ Class: SmallInteger }" |
8485 |xI "{ Class: SmallInteger }" |
8486 yI "{ Class: SmallInteger }" |
8486 yI "{ Class: SmallInteger }" |
8487 wI "{ Class: SmallInteger }" |
8487 wI "{ Class: SmallInteger }" |
8488 hI "{ Class: SmallInteger }"| |
8488 hI "{ Class: SmallInteger }"| |
8489 |
8489 |
8490 xI := x. |
8490 xI := x. |
8491 yI := y. |
8491 yI := y. |
8492 wI := w. |
8492 wI := w. |
8511 toDo idx pixel w h| |
8511 toDo idx pixel w h| |
8512 |
8512 |
8513 w := self width. |
8513 w := self width. |
8514 h := self height. |
8514 h := self height. |
8515 |
8515 |
8516 surroundingPixelsOfDo := |
8516 surroundingPixelsOfDo := |
8517 [:pX :pY :fn | |
8517 [:pX :pY :fn | |
8518 |nX nY| |
8518 |nX nY| |
8519 |
8519 |
8520 nX := pX + 1. |
8520 nX := pX + 1. |
8521 nY := pY + 1. |
8521 nY := pY + 1. |
8522 (nY < h) ifTrue: [fn value:pX value:nY]. |
8522 (nY < h) ifTrue: [fn value:pX value:nY]. |
8523 (pY > 0) ifTrue: [fn value:pX value:(pY - 1)]. |
8523 (pY > 0) ifTrue: [fn value:pX value:(pY - 1)]. |
8524 (nX < w) ifTrue: [fn value:nX value:pY]. |
8524 (nX < w) ifTrue: [fn value:nX value:pY]. |
8525 (pX > 0) ifTrue: [fn value:(pX - 1) value:pY]. |
8525 (pX > 0) ifTrue: [fn value:(pX - 1) value:pY]. |
8526 ]. |
8526 ]. |
8527 |
8527 |
8528 enumerateDetectedPixelsAndDo := |
8528 enumerateDetectedPixelsAndDo := |
8529 [:detectedPixels :action | |
8529 [:detectedPixels :action | |
8530 |idx| |
8530 |idx| |
8531 |
8531 |
8532 idx := 1. |
8532 idx := 1. |
8533 0 to:h-1 do:[:y | |
8533 0 to:h-1 do:[:y | |
8534 0 to:w-1 do:[:x | |
8534 0 to:w-1 do:[:x | |
8535 (detectedPixels at:idx) ifTrue:[ |
8535 (detectedPixels at:idx) ifTrue:[ |
8536 action value:x value:y |
8536 action value:x value:y |
8537 ]. |
8537 ]. |
8538 idx := idx + 1. |
8538 idx := idx + 1. |
8539 ]. |
8539 ]. |
8540 ]. |
8540 ]. |
8541 ]. |
8541 ]. |
8542 |
8542 |
8543 processPixelToFill := [:spX :spY | |
8543 processPixelToFill := [:spX :spY | |
8544 |sp idx| |
8544 |sp idx| |
8545 |
8545 |
8546 ((self pixelAtX:spX y:spY) == detectedPixel and: [mask isNil or:[(mask pixelAtX:spX y:spY) == 1]]) |
8546 ((self pixelAtX:spX y:spY) == detectedPixel and: [mask isNil or:[(mask pixelAtX:spX y:spY) == 1]]) |
8547 ifTrue: [ |
8547 ifTrue: [ |
8548 idx := 1 + spX + (spY * w). |
8548 idx := 1 + spX + (spY * w). |
8549 (allDetectedPixelCoordinates at:idx) ifFalse:[ |
8549 (allDetectedPixelCoordinates at:idx) ifFalse:[ |
8550 allDetectedPixelCoordinates at:idx put:true. |
8550 allDetectedPixelCoordinates at:idx put:true. |
8551 toDo add:spX @ spY. |
8551 toDo add:spX @ spY. |
8552 ]. |
8552 ]. |
8553 ] |
8553 ] |
8554 ]. |
8554 ]. |
8555 |
8555 |
8556 (mask notNil and: [(mask pixelAt:aPoint) == 0]) ifTrue:[ |
8556 (mask notNil and: [(mask pixelAt:aPoint) == 0]) ifTrue:[ |
8557 allDetectedPixelCoordinates := mask floodFillAt: aPoint withColor: Color white. |
8557 allDetectedPixelCoordinates := mask floodFillAt: aPoint withColor: Color white. |
8558 enumerateDetectedPixelsAndDo |
8558 enumerateDetectedPixelsAndDo |
8559 value:allDetectedPixelCoordinates |
8559 value:allDetectedPixelCoordinates |
8560 value:[:x :y | self atImageAndMask:(x@y) put: aColor]. |
8560 value:[:x :y | self atImageAndMask:(x@y) put: aColor]. |
8561 ^ allDetectedPixelCoordinates |
8561 ^ allDetectedPixelCoordinates |
8562 ]. |
8562 ]. |
8563 |
8563 |
8564 detectedPixel := self pixelAt: aPoint. |
8564 detectedPixel := self pixelAt: aPoint. |
8565 |
8565 |
8566 allDetectedPixelCoordinates := BooleanArray new:(w * h). |
8566 allDetectedPixelCoordinates := BooleanArray new:(w * h). |
8567 toDo := OrderedCollection new:1000. |
8567 toDo := OrderedCollection new:1000. |
8568 allDetectedPixelCoordinates at:(1 + aPoint x + (aPoint y * w)) put:true. |
8568 allDetectedPixelCoordinates at:(1 + aPoint x + (aPoint y * w)) put:true. |
8569 toDo add:aPoint. |
8569 toDo add:aPoint. |
8570 |
8570 |
8571 [toDo notEmpty] whileTrue:[ |
8571 [toDo notEmpty] whileTrue:[ |
8572 |p| |
8572 |p| |
8573 |
8573 |
8574 p := toDo removeFirst. |
8574 p := toDo removeFirst. |
8575 surroundingPixelsOfDo value:p x value:p y value:processPixelToFill. |
8575 surroundingPixelsOfDo value:p x value:p y value:processPixelToFill. |
8576 ]. |
8576 ]. |
8577 |
8577 |
8578 idx := 1. |
8578 idx := 1. |
8579 aColor redByte notNil ifTrue:[ |
8579 aColor redByte notNil ifTrue:[ |
8580 pixel := self valueFromColor:aColor. |
8580 pixel := self valueFromColor:aColor. |
8581 ]. |
8581 ]. |
8582 |
8582 |
8583 pixel isNil ifTrue:[ |
8583 pixel isNil ifTrue:[ |
8584 enumerateDetectedPixelsAndDo |
8584 enumerateDetectedPixelsAndDo |
8585 value:allDetectedPixelCoordinates |
8585 value:allDetectedPixelCoordinates |
8586 value:[:x :y | mask pixelAtX:x y:y put:0]. |
8586 value:[:x :y | mask pixelAtX:x y:y put:0]. |
8587 ] ifFalse:[ |
8587 ] ifFalse:[ |
8588 enumerateDetectedPixelsAndDo |
8588 enumerateDetectedPixelsAndDo |
8589 value:allDetectedPixelCoordinates |
8589 value:allDetectedPixelCoordinates |
8590 value:[:x :y | self pixelAtX:x y:y put:pixel]. |
8590 value:[:x :y | self pixelAtX:x y:y put:pixel]. |
8591 ]. |
8591 ]. |
8592 ^ allDetectedPixelCoordinates |
8592 ^ allDetectedPixelCoordinates |
8593 |
8593 |
8594 "Modified: / 29.7.1998 / 03:09:16 / cg" |
8594 "Modified: / 29.7.1998 / 03:09:16 / cg" |
8595 ! |
8595 ! |
8657 yR| |
8657 yR| |
8658 |
8658 |
8659 yS := yStart. |
8659 yS := yStart. |
8660 yE := yEnd. |
8660 yE := yEnd. |
8661 |
8661 |
8662 yS to:yE do:[:yRun | |
8662 yS to:yE do:[:yRun | |
8663 yR := yRun. |
8663 yR := yRun. |
8664 self colorsAtY:yRun from:xStart to:xEnd do:[:xRun :color | |
8664 self colorsAtY:yRun from:xStart to:xEnd do:[:xRun :color | |
8665 aBlock value:xRun value:yR value:color |
8665 aBlock value:xRun value:yR value:color |
8666 ] |
8666 ] |
8667 ] |
8667 ] |
8668 |
8668 |
8669 "Modified: 11.7.1996 / 19:50:47 / cg" |
8669 "Modified: 11.7.1996 / 19:50:47 / cg" |
8670 ! |
8670 ! |
8680 |
8680 |
8681 "Modified: 7.6.1996 / 19:11:06 / cg" |
8681 "Modified: 7.6.1996 / 19:11:06 / cg" |
8682 ! |
8682 ! |
8683 |
8683 |
8684 valuesAtY:y from:x1 to:x2 do:aBlock |
8684 valuesAtY:y from:x1 to:x2 do:aBlock |
8685 "WARNING: for now, this enumerates pixel values |
8685 "WARNING: for now, this enumerates pixel values |
8686 (backward compatibility with ST/X) |
8686 (backward compatibility with ST/X) |
8687 In the future, this will enumerate colors |
8687 In the future, this will enumerate colors |
8688 Use #pixelAtT:from:to:do: - for future compatibility. |
8688 Use #pixelAtT:from:to:do: - for future compatibility. |
8689 |
8689 |
8690 perform aBlock for each pixelValue from x1 to x2 in row y. |
8690 perform aBlock for each pixelValue from x1 to x2 in row y. |
8691 Notice, that x and y coordinates start at 0@0 for the upper left corner. |
8691 Notice, that x and y coordinates start at 0@0 for the upper left corner. |
8692 The block is passed the x coordinate and the pixelValue at each pixel. |
8692 The block is passed the x coordinate and the pixelValue at each pixel. |
8719 |xS "{Class: SmallInteger }" |
8719 |xS "{Class: SmallInteger }" |
8720 xE "{Class: SmallInteger }"| |
8720 xE "{Class: SmallInteger }"| |
8721 |
8721 |
8722 xS := xStart. |
8722 xS := xStart. |
8723 xE := xEnd. |
8723 xE := xEnd. |
8724 yStart to:yEnd do:[:yRun | |
8724 yStart to:yEnd do:[:yRun | |
8725 self valuesAtY:yRun from:xStart to:xEnd do:[:xRun :pixel | |
8725 self valuesAtY:yRun from:xStart to:xEnd do:[:xRun :pixel | |
8726 aBlock value:xRun value:yRun value:pixel |
8726 aBlock value:xRun value:yRun value:pixel |
8727 ] |
8727 ] |
8728 ] |
8728 ] |
8729 |
8729 |
8743 "some Image has been collected - nothing to do" |
8743 "some Image has been collected - nothing to do" |
8744 ! ! |
8744 ! ! |
8745 |
8745 |
8746 !Image methodsFor:'image manipulations'! |
8746 !Image methodsFor:'image manipulations'! |
8747 |
8747 |
8748 applyPixelValuesTo:pixelFunctionBlock in:aRectangle into:newImage |
8748 applyPixelValuesTo:pixelFunctionBlock in:aRectangle into:newImage |
8749 "helper for withPixelFunctionAppliedToValues: |
8749 "helper for withPixelFunctionAppliedToValues: |
8750 enumerate pixelValues and evaluate the block for each. |
8750 enumerate pixelValues and evaluate the block for each. |
8751 Could be redefined by subclasses for better performance." |
8751 Could be redefined by subclasses for better performance." |
8752 |
8752 |
8753 |w "{Class: SmallInteger }" |
8753 |w "{Class: SmallInteger }" |
8805 |
8805 |
8806 applyPixelValuesTo:pixelFunctionBlock into:newImage |
8806 applyPixelValuesTo:pixelFunctionBlock into:newImage |
8807 "helper for withPixelFunctionAppliedToValues: |
8807 "helper for withPixelFunctionAppliedToValues: |
8808 enumerate pixelValues and evaluate the block for each." |
8808 enumerate pixelValues and evaluate the block for each." |
8809 |
8809 |
8810 ^ self |
8810 ^ self |
8811 applyPixelValuesTo:pixelFunctionBlock |
8811 applyPixelValuesTo:pixelFunctionBlock |
8812 in:(0@0 corner:width@height) |
8812 in:(0@0 corner:width@height) |
8813 into:newImage |
8813 into:newImage |
8814 ! |
8814 ! |
8815 |
8815 |
8816 blendWith:aColor |
8816 blendWith:aColor |
8817 "return a new image which is blended with some color. |
8817 "return a new image which is blended with some color. |
8818 The receiver must be a palette image (currently). |
8818 The receiver must be a palette image (currently). |
8819 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
8819 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
8820 CAVEAT: Need an argument, which specifies by how much it should be lighter." |
8820 CAVEAT: Need an argument, which specifies by how much it should be lighter." |
8821 |
8821 |
8822 ^ self |
8822 ^ self |
8823 copyWithColorMapProcessing:[:clr | clr blendWith:aColor] |
8823 copyWithColorMapProcessing:[:clr | clr blendWith:aColor] |
8824 |
8824 |
8825 " |
8825 " |
8826 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
8826 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
8827 ((Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') blendWith:Color red) inspect |
8827 ((Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') blendWith:Color red) inspect |
8832 "Modified: 24.4.1997 / 18:31:23 / cg" |
8832 "Modified: 24.4.1997 / 18:31:23 / cg" |
8833 ! |
8833 ! |
8834 |
8834 |
8835 colorMapProcessing:aBlock |
8835 colorMapProcessing:aBlock |
8836 "a helper for all kinds of colormap manipulations. |
8836 "a helper for all kinds of colormap manipulations. |
8837 The argument, aBlock is called for every colormap entry, |
8837 The argument, aBlock is called for every colormap entry, |
8838 and the returned value will replace the original entry in the map. |
8838 and the returned value will replace the original entry in the map. |
8839 This will fail for non-palette images. |
8839 This will fail for non-palette images. |
8840 See examples in Image>>copyWithColorMapProcessing:" |
8840 See examples in Image>>copyWithColorMapProcessing:" |
8841 |
8841 |
8842 |nColors "{ Class: SmallInteger }"| |
8842 |nColors "{ Class: SmallInteger }"| |
8870 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale)" |
8870 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale)" |
8871 |
8871 |
8872 |newImage| |
8872 |newImage| |
8873 |
8873 |
8874 self colorMap isNil ifTrue:[ |
8874 self colorMap isNil ifTrue:[ |
8875 ^ self withPixelFunctionApplied:[:orig :clr :x :y | aBlock value:clr] |
8875 ^ self withPixelFunctionApplied:[:orig :clr :x :y | aBlock value:clr] |
8876 "/ self error:'no colormap in image'. |
8876 "/ self error:'no colormap in image'. |
8877 "/ ^ nil |
8877 "/ ^ nil |
8878 ]. |
8878 ]. |
8879 |
8879 |
8880 " |
8880 " |
8886 ^ newImage |
8886 ^ newImage |
8887 |
8887 |
8888 " |
8888 " |
8889 leave red component only: |
8889 leave red component only: |
8890 |
8890 |
8891 (Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
8891 (Image fromFile:'goodies/bitmaps/gifImages/claus.gif') |
8892 copyWithColorMapProcessing:[:clr | Color red:(clr red) green:0 blue:0] |
8892 copyWithColorMapProcessing:[:clr | Color red:(clr red) green:0 blue:0] |
8893 " |
8893 " |
8894 |
8894 |
8895 " |
8895 " |
8896 make it reddish: |
8896 make it reddish: |
8897 |
8897 |
8898 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8898 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8899 copyWithColorMapProcessing:[:clr | Color red:((clr red * 2) min:100) green:clr green blue:clr blue] |
8899 copyWithColorMapProcessing:[:clr | Color red:((clr red * 2) min:100) green:clr green blue:clr blue] |
8900 " |
8900 " |
8901 |
8901 |
8902 " |
8902 " |
8903 invert: |
8903 invert: |
8904 |
8904 |
8905 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8905 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8906 copyWithColorMapProcessing:[:clr | Color red:(100 - clr red) green:(100 - clr green) blue:(100 - clr green)] |
8906 copyWithColorMapProcessing:[:clr | Color red:(100 - clr red) green:(100 - clr green) blue:(100 - clr green)] |
8907 " |
8907 " |
8908 |
8908 |
8909 " |
8909 " |
8910 lighter: |
8910 lighter: |
8911 |
8911 |
8912 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8912 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8913 copyWithColorMapProcessing:[:clr | |r g b| |
8913 copyWithColorMapProcessing:[:clr | |r g b| |
8914 r := clr red. g := clr green. b := clr blue. |
8914 r := clr red. g := clr green. b := clr blue. |
8915 Color red:(r + (100-r//2)) |
8915 Color red:(r + (100-r//2)) |
8916 green:(g + (100-g//2)) |
8916 green:(g + (100-g//2)) |
8917 blue:(b + (100-b//2))] |
8917 blue:(b + (100-b//2))] |
8918 " |
8918 " |
8919 |
8919 |
8920 " |
8920 " |
8921 darker: |
8921 darker: |
8922 |
8922 |
8923 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8923 (Image fromFile:'bitmaps/gifImages/claus.gif') |
8924 copyWithColorMapProcessing:[:clr | Color red:(clr red//2) green:(clr green // 2) blue:(clr blue // 2)] |
8924 copyWithColorMapProcessing:[:clr | Color red:(clr red//2) green:(clr green // 2) blue:(clr blue // 2)] |
8925 " |
8925 " |
8926 |
8926 |
8927 "Modified: 24.4.1997 / 18:28:05 / cg" |
8927 "Modified: 24.4.1997 / 18:28:05 / cg" |
8928 ! |
8928 ! |
8929 |
8929 |
8941 "return a new image which is slightly darker than the receiver. |
8941 "return a new image which is slightly darker than the receiver. |
8942 The receiver must be a palette image (currently). |
8942 The receiver must be a palette image (currently). |
8943 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
8943 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
8944 CAVEAT: Need an argument, which specifies by how much it should be darker." |
8944 CAVEAT: Need an argument, which specifies by how much it should be darker." |
8945 |
8945 |
8946 ^ self |
8946 ^ self |
8947 copyWithColorMapProcessing:[:clr | clr darkened] |
8947 copyWithColorMapProcessing:[:clr | clr darkened] |
8948 |
8948 |
8949 " |
8949 " |
8950 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
8950 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
8951 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') darkened inspect |
8951 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') darkened inspect |
9037 flipVertical |
9037 flipVertical |
9038 "inplace vertical flip" |
9038 "inplace vertical flip" |
9039 |
9039 |
9040 |h "{Class: SmallInteger }" |
9040 |h "{Class: SmallInteger }" |
9041 bytesPerRow "{Class: SmallInteger }" |
9041 bytesPerRow "{Class: SmallInteger }" |
9042 buffer |
9042 buffer |
9043 indexLow "{Class: SmallInteger }" |
9043 indexLow "{Class: SmallInteger }" |
9044 indexHi "{Class: SmallInteger }" |
9044 indexHi "{Class: SmallInteger }" |
9045 bytes| |
9045 bytes| |
9046 |
9046 |
9047 bytes := self bits. |
9047 bytes := self bits. |
9088 hardMagnifiedBy:scalePoint |
9088 hardMagnifiedBy:scalePoint |
9089 "return a new image magnified by scalePoint, aPoint. |
9089 "return a new image magnified by scalePoint, aPoint. |
9090 This is the general magnification method, handling non-integral values. |
9090 This is the general magnification method, handling non-integral values. |
9091 It is slower than the integral magnification method." |
9091 It is slower than the integral magnification method." |
9092 |
9092 |
9093 |mX |
9093 |mX |
9094 mY |
9094 mY |
9095 newWidth "{ Class: SmallInteger }" |
9095 newWidth "{ Class: SmallInteger }" |
9096 newHeight "{ Class: SmallInteger }" |
9096 newHeight "{ Class: SmallInteger }" |
9097 w "{ Class: SmallInteger }" |
9097 w "{ Class: SmallInteger }" |
9098 h "{ Class: SmallInteger }" |
9098 h "{ Class: SmallInteger }" |
9099 newImage newBits bitsPerPixel newBytesPerRow newMask |
9099 newImage newBits bitsPerPixel newBytesPerRow newMask |
9100 value |
9100 value |
9101 srcRow pixelArray| |
9101 srcRow pixelArray| |
9102 |
9102 |
9103 mX := scalePoint x. |
9103 mX := scalePoint x. |
9104 mY := scalePoint y. |
9104 mY := scalePoint y. |
9105 ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. |
9105 ((mX < 0) or:[mY < 0]) ifTrue:[^ nil]. |
9115 mask notNil ifTrue:[ |
9115 mask notNil ifTrue:[ |
9116 newMask := (mask magnifiedBy:scalePoint) |
9116 newMask := (mask magnifiedBy:scalePoint) |
9117 ]. |
9117 ]. |
9118 |
9118 |
9119 newImage := self species new. |
9119 newImage := self species new. |
9120 newImage |
9120 newImage |
9121 width:newWidth |
9121 width:newWidth |
9122 height:newHeight |
9122 height:newHeight |
9123 photometric:photometric |
9123 photometric:photometric |
9124 samplesPerPixel:samplesPerPixel |
9124 samplesPerPixel:samplesPerPixel |
9125 bitsPerSample:bitsPerSample |
9125 bitsPerSample:bitsPerSample |
9126 colorMap:colorMap copy |
9126 colorMap:colorMap copy |
9127 bits:newBits |
9127 bits:newBits |
9128 mask:newMask. |
9128 mask:newMask. |
9129 |
9129 |
9130 "walk over destination image fetching pixels from source image" |
9130 "walk over destination image fetching pixels from source image" |
9156 "Modified: 24.4.1997 / 18:30:24 / cg" |
9156 "Modified: 24.4.1997 / 18:30:24 / cg" |
9157 ! |
9157 ! |
9158 |
9158 |
9159 hardRotated:degrees |
9159 hardRotated:degrees |
9160 "return a new image from the old one, by rotating the image |
9160 "return a new image from the old one, by rotating the image |
9161 degrees clockwise. |
9161 degrees clockwise. |
9162 Warning: the returned image will be larger than the original image." |
9162 Warning: the returned image will be larger than the original image." |
9163 |
9163 |
9164 |p r a aN p1 p2 p3 p4 maxX minX maxY minY |
9164 |p r a aN p1 p2 p3 p4 maxX minX maxY minY |
9165 newImage |
9165 newImage |
9166 newWidth "{ Class: SmallInteger }" |
9166 newWidth "{ Class: SmallInteger }" |
9167 newHeight "{ Class: SmallInteger }" |
9167 newHeight "{ Class: SmallInteger }" |
9168 newBytesPerRow newBits |
9168 newBytesPerRow newBits |
9169 blackPixel halfW halfH radians m t bad |
9169 blackPixel halfW halfH radians m t bad |
9170 bytesPerRow myDepth maskBits |
9170 bytesPerRow myDepth maskBits |
9171 pX pY srcX srcY pix nX nY |
9171 pX pY srcX srcY pix nX nY |
9172 sinRot cosRot sinPY cosPY| |
9172 sinRot cosRot sinPY cosPY| |
9173 |
9173 |
9174 radians := degrees degreesToRadians. |
9174 radians := degrees degreesToRadians. |
9175 |
9175 |
9176 "/ placing the image at the origin, |
9176 "/ placing the image at the origin, |
9178 |
9178 |
9179 p := (width - 1 / 2) @ (height - 1 / 2). |
9179 p := (width - 1 / 2) @ (height - 1 / 2). |
9180 r := p r. |
9180 r := p r. |
9181 a := p theta. |
9181 a := p theta. |
9182 |
9182 |
9183 "/ add the rotation |
9183 "/ add the rotation |
9184 "/ (sight - subtract, we defined things clockwise ... |
9184 "/ (sight - subtract, we defined things clockwise ... |
9185 "/ ... in contrast to point which thinks counter-clockwise) |
9185 "/ ... in contrast to point which thinks counter-clockwise) |
9186 |
9186 |
9187 aN := a - radians. |
9187 aN := a - radians. |
9188 |
9188 |
9189 "/ compute new corner points |
9189 "/ compute new corner points |
9194 |
9194 |
9195 "/ compute the boundary of the new image |
9195 "/ compute the boundary of the new image |
9196 |
9196 |
9197 maxX := minX := p1 x. |
9197 maxX := minX := p1 x. |
9198 (t := p2 x) > maxX ifTrue:[ |
9198 (t := p2 x) > maxX ifTrue:[ |
9199 maxX := t |
9199 maxX := t |
9200 ] ifFalse:[ |
9200 ] ifFalse:[ |
9201 t < minX ifTrue:[minX := t]. |
9201 t < minX ifTrue:[minX := t]. |
9202 ]. |
9202 ]. |
9203 (t := p3 x) > maxX ifTrue:[ |
9203 (t := p3 x) > maxX ifTrue:[ |
9204 maxX := t |
9204 maxX := t |
9205 ] ifFalse:[ |
9205 ] ifFalse:[ |
9206 t < minX ifTrue:[minX := t]. |
9206 t < minX ifTrue:[minX := t]. |
9207 ]. |
9207 ]. |
9208 (t := p4 x) > maxX ifTrue:[ |
9208 (t := p4 x) > maxX ifTrue:[ |
9209 maxX := t |
9209 maxX := t |
9210 ] ifFalse:[ |
9210 ] ifFalse:[ |
9211 t < minX ifTrue:[minX := t]. |
9211 t < minX ifTrue:[minX := t]. |
9212 ]. |
9212 ]. |
9213 |
9213 |
9214 maxY := minY := p1 y. |
9214 maxY := minY := p1 y. |
9215 (t := p2 y) > maxY ifTrue:[ |
9215 (t := p2 y) > maxY ifTrue:[ |
9216 maxY := t |
9216 maxY := t |
9217 ] ifFalse:[ |
9217 ] ifFalse:[ |
9218 t < minY ifTrue:[minY := t]. |
9218 t < minY ifTrue:[minY := t]. |
9219 ]. |
9219 ]. |
9220 (t := p3 y) > maxY ifTrue:[ |
9220 (t := p3 y) > maxY ifTrue:[ |
9221 maxY := t |
9221 maxY := t |
9222 ] ifFalse:[ |
9222 ] ifFalse:[ |
9223 t < minY ifTrue:[minY := t]. |
9223 t < minY ifTrue:[minY := t]. |
9224 ]. |
9224 ]. |
9225 (t := p4 y) > maxY ifTrue:[ |
9225 (t := p4 y) > maxY ifTrue:[ |
9226 maxY := t |
9226 maxY := t |
9227 ] ifFalse:[ |
9227 ] ifFalse:[ |
9228 t < minY ifTrue:[minY := t]. |
9228 t < minY ifTrue:[minY := t]. |
9229 ]. |
9229 ]. |
9230 |
9230 |
9231 |
9231 |
9232 newWidth := (maxX - minX) rounded + 1. |
9232 newWidth := (maxX - minX) rounded + 1. |
9233 newHeight := (maxY - minY) rounded + 1. |
9233 newHeight := (maxY - minY) rounded + 1. |
9242 newImage samplesPerPixel:samplesPerPixel. |
9242 newImage samplesPerPixel:samplesPerPixel. |
9243 newImage bitsPerSample:bitsPerSample. |
9243 newImage bitsPerSample:bitsPerSample. |
9244 newImage colorMap:colorMap copy. |
9244 newImage colorMap:colorMap copy. |
9245 newImage maskedPixelsAre0:maskedPixelsAre0. |
9245 newImage maskedPixelsAre0:maskedPixelsAre0. |
9246 mask notNil ifTrue:[ |
9246 mask notNil ifTrue:[ |
9247 newImage mask:(mask rotated:degrees) |
9247 newImage mask:(mask rotated:degrees) |
9248 ] ifFalse:[ |
9248 ] ifFalse:[ |
9249 self isMask ifFalse:[ |
9249 self isMask ifFalse:[ |
9250 self depth ~~ 1 ifTrue:[ |
9250 self depth ~~ 1 ifTrue:[ |
9251 m := ImageMask width:width height:height. |
9251 m := ImageMask width:width height:height. |
9252 m bits:(maskBits := ByteArray new:(m bytesPerRow * height)). |
9252 m bits:(maskBits := ByteArray new:(m bytesPerRow * height)). |
9253 maskBits atAllPut:16rFF. |
9253 maskBits atAllPut:16rFF. |
9254 newImage mask:(m rotated:degrees) |
9254 newImage mask:(m rotated:degrees) |
9255 ] |
9255 ] |
9256 ] |
9256 ] |
9257 ]. |
9257 ]. |
9258 |
9258 |
9259 maskedPixelsAre0 ifTrue:[ |
9259 maskedPixelsAre0 ifTrue:[ |
9260 blackPixel := 0. |
9260 blackPixel := 0. |
9261 ] ifFalse:[ |
9261 ] ifFalse:[ |
9262 blackPixel := self valueFromColor:Color black. |
9262 blackPixel := self valueFromColor:Color black. |
9263 blackPixel isNil ifTrue:[ |
9263 blackPixel isNil ifTrue:[ |
9264 blackPixel := self valueFromColor:Color white. |
9264 blackPixel := self valueFromColor:Color white. |
9265 blackPixel isNil ifTrue:[ |
9265 blackPixel isNil ifTrue:[ |
9266 blackPixel := 0. |
9266 blackPixel := 0. |
9267 ] |
9267 ] |
9268 ] |
9268 ] |
9269 ]. |
9269 ]. |
9270 self isMask ifTrue:[ |
9270 self isMask ifTrue:[ |
9271 blackPixel := 0. |
9271 blackPixel := 0. |
9272 ]. |
9272 ]. |
9273 |
9273 |
9274 myDepth := self depth. |
9274 myDepth := self depth. |
9275 newBits atAllPut:0. |
9275 newBits atAllPut:0. |
9276 |
9276 |
9277 "/ now, walk over destination pixels, |
9277 "/ now, walk over destination pixels, |
9278 "/ fetching from source. |
9278 "/ fetching from source. |
9279 "/ (if we walked over the source, we could get holes |
9279 "/ (if we walked over the source, we could get holes |
9280 "/ in the destination image ...) |
9280 "/ in the destination image ...) |
9281 |
9281 |
9282 halfW := (width - 1) / 2.0. |
9282 halfW := (width - 1) / 2.0. |
9283 halfH := (height - 1) / 2.0. |
9283 halfH := (height - 1) / 2.0. |
9303 double sin(), cos(); |
9303 double sin(), cos(); |
9304 # define Float_PI 3.14159 |
9304 # define Float_PI 3.14159 |
9305 |
9305 |
9306 bad = true; |
9306 bad = true; |
9307 if (1 |
9307 if (1 |
9308 && __isFloat(minX) |
9308 && __isFloat(minX) |
9309 && __isFloat(minY) |
9309 && __isFloat(minY) |
9310 && __isFloat(radians) |
9310 && __isFloat(radians) |
9311 && __isFloat(halfW) |
9311 && __isFloat(halfW) |
9312 && __isFloat(halfH) |
9312 && __isFloat(halfH) |
9313 && __isByteArray(newBits) |
9313 && __isByteArray(newBits) |
9314 && __isByteArray(__INST(bytes))) { |
9314 && __isByteArray(__INST(bytes))) { |
9315 __srcBytes = __ByteArrayInstPtr(__INST(bytes))->ba_element; |
9315 __srcBytes = __ByteArrayInstPtr(__INST(bytes))->ba_element; |
9316 __dstBytes = __ByteArrayInstPtr(newBits)->ba_element; |
9316 __dstBytes = __ByteArrayInstPtr(newBits)->ba_element; |
9317 __nSrcBytes = __byteArraySize(__INST(bytes)); |
9317 __nSrcBytes = __byteArraySize(__INST(bytes)); |
9318 __nDstBytes = __byteArraySize(newBits); |
9318 __nDstBytes = __byteArraySize(newBits); |
9319 __blackPixel = __intVal(blackPixel); |
9319 __blackPixel = __intVal(blackPixel); |
9320 |
9320 |
9321 __radians = __floatVal(radians); |
9321 __radians = __floatVal(radians); |
9322 __radians = -__radians; /* sigh: clock-wise */ |
9322 __radians = -__radians; /* sigh: clock-wise */ |
9323 __sin = sin(__radians); |
9323 __sin = sin(__radians); |
9324 __cos = cos(__radians); |
9324 __cos = cos(__radians); |
9325 __minX = __floatVal(minX); |
9325 __minX = __floatVal(minX); |
9326 __minY = __floatVal(minY); |
9326 __minY = __floatVal(minY); |
9327 __halfW = __floatVal(halfW); |
9327 __halfW = __floatVal(halfW); |
9328 __halfH = __floatVal(halfH); |
9328 __halfH = __floatVal(halfH); |
9329 |
9329 |
9330 __dstRowPtr = __dstBytes; |
9330 __dstRowPtr = __dstBytes; |
9331 __dstEndPtr = __dstBytes + __nDstBytes; |
9331 __dstEndPtr = __dstBytes + __nDstBytes; |
9332 |
9332 |
9333 # define EARLY_OUT |
9333 # define EARLY_OUT |
9334 # define FAST_ADVANCE 5 |
9334 # define FAST_ADVANCE 5 |
9335 # define FAST_ADVANCE2 |
9335 # define FAST_ADVANCE2 |
9336 |
9336 |
9337 switch (__depth) { |
9337 switch (__depth) { |
9338 case 8: |
9338 case 8: |
9339 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9339 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9340 double __pY, __sinPY, __cosPY; |
9340 double __pY, __sinPY, __cosPY; |
9341 #ifdef EARLY_OUT |
9341 #ifdef EARLY_OUT |
9342 int didFetchInRow = 0; |
9342 int didFetchInRow = 0; |
9343 #endif |
9343 #endif |
9344 __pY = (double)(__dstY + __minY); |
9344 __pY = (double)(__dstY + __minY); |
9345 |
9345 |
9346 __sinPY = __sin * __pY; |
9346 __sinPY = __sin * __pY; |
9347 __cosPY = __cos * __pY; |
9347 __cosPY = __cos * __pY; |
9348 |
9348 |
9349 __dstPtr = __dstRowPtr; |
9349 __dstPtr = __dstRowPtr; |
9350 __dstRowPtr += __dstBytesPerRow; |
9350 __dstRowPtr += __dstBytesPerRow; |
9351 |
9351 |
9352 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9352 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9353 double __pX, __nX; |
9353 double __pX, __nX; |
9354 unsigned __pix; |
9354 unsigned __pix; |
9355 |
9355 |
9356 /* translate X in destination (center to 0/0) */ |
9356 /* translate X in destination (center to 0/0) */ |
9357 __pX = (double)(__dstX + __minX); |
9357 __pX = (double)(__dstX + __minX); |
9358 /* rotate X */ |
9358 /* rotate X */ |
9359 __nX = (__cos * __pX) - __sinPY; |
9359 __nX = (__cos * __pX) - __sinPY; |
9360 |
9360 |
9361 /* translate X in source (origin to 0/0) */ |
9361 /* translate X in source (origin to 0/0) */ |
9362 __nX = __nX + __halfW + 0.5; |
9362 __nX = __nX + __halfW + 0.5; |
9363 |
9363 |
9364 /* inside ? */ |
9364 /* inside ? */ |
9365 if (__nX < 0) { |
9365 if (__nX < 0) { |
9366 #ifdef EARLY_OUT |
9366 #ifdef EARLY_OUT |
9367 if (didFetchInRow) { |
9367 if (didFetchInRow) { |
9368 break; |
9368 break; |
9369 } |
9369 } |
9370 #endif |
9370 #endif |
9371 #ifdef FAST_ADVANCE |
9371 #ifdef FAST_ADVANCE |
9372 if (__blackPixel == 0) { |
9372 if (__blackPixel == 0) { |
9373 do { |
9373 do { |
9374 /* try advance by FAST_ADVANCE pixels ... */ |
9374 /* try advance by FAST_ADVANCE pixels ... */ |
9375 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9375 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9376 if (__dstX >= __newWidth) { |
9376 if (__dstX >= __newWidth) { |
9377 break; |
9377 break; |
9378 } |
9378 } |
9379 __pX = (double)(__dstX + __minX); |
9379 __pX = (double)(__dstX + __minX); |
9380 __nX = (__cos * __pX) - __sinPY; |
9380 __nX = (__cos * __pX) - __sinPY; |
9381 __nX = __nX + __halfW + 0.5; |
9381 __nX = __nX + __halfW + 0.5; |
9382 } while (__nX < 0); |
9382 } while (__nX < 0); |
9383 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9383 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9384 } |
9384 } |
9385 #endif |
9385 #endif |
9386 __pix = __blackPixel; |
9386 __pix = __blackPixel; |
9387 } else { |
9387 } else { |
9388 int __srcX; |
9388 int __srcX; |
9389 |
9389 |
9390 __srcX = (int)__nX; |
9390 __srcX = (int)__nX; |
9391 /* inside ? */ |
9391 /* inside ? */ |
9392 if (__srcX >= __width) { |
9392 if (__srcX >= __width) { |
9393 #ifdef EARLY_OUT |
9393 #ifdef EARLY_OUT |
9394 if (didFetchInRow) { |
9394 if (didFetchInRow) { |
9395 break; |
9395 break; |
9396 } |
9396 } |
9397 #endif |
9397 #endif |
9398 #ifdef FAST_ADVANCE2 |
9398 #ifdef FAST_ADVANCE2 |
9399 if (__blackPixel == 0) { |
9399 if (__blackPixel == 0) { |
9400 do { |
9400 do { |
9401 /* try advance by FAST_ADVANCE pixels ... */ |
9401 /* try advance by FAST_ADVANCE pixels ... */ |
9402 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9402 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9403 if (__dstX >= __newWidth) { |
9403 if (__dstX >= __newWidth) { |
9404 break; |
9404 break; |
9405 } |
9405 } |
9406 __pX = (double)(__dstX + __minX); |
9406 __pX = (double)(__dstX + __minX); |
9407 __nX = (__cos * __pX) - __sinPY; |
9407 __nX = (__cos * __pX) - __sinPY; |
9408 __nX = __nX + __halfW + 0.5; |
9408 __nX = __nX + __halfW + 0.5; |
9409 __srcX = (int)__nX; |
9409 __srcX = (int)__nX; |
9410 } while (__srcX >= __width); |
9410 } while (__srcX >= __width); |
9411 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9411 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9412 } |
9412 } |
9413 #endif |
9413 #endif |
9414 __pix = __blackPixel; |
9414 __pix = __blackPixel; |
9415 } else { |
9415 } else { |
9416 double __nY; |
9416 double __nY; |
9417 |
9417 |
9418 /* rotate Y */ |
9418 /* rotate Y */ |
9419 __nY = (__sin * __pX) + __cosPY; |
9419 __nY = (__sin * __pX) + __cosPY; |
9420 /* translate Y in source (origin to 0/0) */ |
9420 /* translate Y in source (origin to 0/0) */ |
9421 __nY = __nY + __halfH + 0.5; |
9421 __nY = __nY + __halfH + 0.5; |
9422 |
9422 |
9423 /* inside ? */ |
9423 /* inside ? */ |
9424 if (__nY < 0) { |
9424 if (__nY < 0) { |
9425 #ifdef EARLY_OUT |
9425 #ifdef EARLY_OUT |
9426 if (didFetchInRow) { |
9426 if (didFetchInRow) { |
9427 break; |
9427 break; |
9428 } |
9428 } |
9429 #endif |
9429 #endif |
9430 #ifdef FAST_ADVANCE2 |
9430 #ifdef FAST_ADVANCE2 |
9431 if (__blackPixel == 0) { |
9431 if (__blackPixel == 0) { |
9432 do { |
9432 do { |
9433 /* try advance by FAST_ADVANCE pixels ... */ |
9433 /* try advance by FAST_ADVANCE pixels ... */ |
9434 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9434 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9435 if (__dstX >= __newWidth) { |
9435 if (__dstX >= __newWidth) { |
9436 break; |
9436 break; |
9437 } |
9437 } |
9438 __pX = (double)(__dstX + __minX); |
9438 __pX = (double)(__dstX + __minX); |
9439 __nY = (__sin * __pX) + __cosPY; |
9439 __nY = (__sin * __pX) + __cosPY; |
9440 __nY = __nY + __halfH + 0.5; |
9440 __nY = __nY + __halfH + 0.5; |
9441 } while (__nY < 0); |
9441 } while (__nY < 0); |
9442 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9442 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9443 } |
9443 } |
9444 #endif |
9444 #endif |
9445 __pix = __blackPixel; |
9445 __pix = __blackPixel; |
9446 } else { |
9446 } else { |
9447 int __srcY; |
9447 int __srcY; |
9448 |
9448 |
9449 __srcY = (int)__nY; |
9449 __srcY = (int)__nY; |
9450 /* inside ? */ |
9450 /* inside ? */ |
9451 if (__srcY >= __height) { |
9451 if (__srcY >= __height) { |
9452 #ifdef EARLY_OUT |
9452 #ifdef EARLY_OUT |
9453 if (didFetchInRow) { |
9453 if (didFetchInRow) { |
9454 break; |
9454 break; |
9455 } |
9455 } |
9456 #endif |
9456 #endif |
9457 #ifdef FAST_ADVANCE |
9457 #ifdef FAST_ADVANCE |
9458 if (__blackPixel == 0) { |
9458 if (__blackPixel == 0) { |
9459 do { |
9459 do { |
9460 /* try advance by FAST_ADVANCE pixels ... */ |
9460 /* try advance by FAST_ADVANCE pixels ... */ |
9461 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9461 __dstX += FAST_ADVANCE; __dstPtr += FAST_ADVANCE; |
9462 if (__dstX >= __newWidth) { |
9462 if (__dstX >= __newWidth) { |
9463 break; |
9463 break; |
9464 } |
9464 } |
9465 __pX = (double)(__dstX + __minX); |
9465 __pX = (double)(__dstX + __minX); |
9466 __nY = (__sin * __pX) + __cosPY; |
9466 __nY = (__sin * __pX) + __cosPY; |
9467 __nY = __nY + __halfH + 0.5; |
9467 __nY = __nY + __halfH + 0.5; |
9468 __srcY = (int)__nY; |
9468 __srcY = (int)__nY; |
9469 } while (__srcY >= __height); |
9469 } while (__srcY >= __height); |
9470 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9470 __dstX -= FAST_ADVANCE; __dstPtr -= FAST_ADVANCE; |
9471 } |
9471 } |
9472 #endif |
9472 #endif |
9473 __pix = __blackPixel; |
9473 __pix = __blackPixel; |
9474 } else { |
9474 } else { |
9475 /* fetch source pixel */ |
9475 /* fetch source pixel */ |
9476 |
9476 |
9477 int idx; |
9477 int idx; |
9478 #ifdef EARLY_OUT |
9478 #ifdef EARLY_OUT |
9479 didFetchInRow = 1; |
9479 didFetchInRow = 1; |
9480 #endif |
9480 #endif |
9481 idx = __srcY * __srcBytesPerRow + __srcX; |
9481 idx = __srcY * __srcBytesPerRow + __srcX; |
9482 if ((unsigned)idx < __nSrcBytes) { |
9482 if ((unsigned)idx < __nSrcBytes) { |
9483 __pix = __srcBytes[idx]; |
9483 __pix = __srcBytes[idx]; |
9484 } else { |
9484 } else { |
9485 __pix = __blackPixel; |
9485 __pix = __blackPixel; |
9486 } |
9486 } |
9487 } |
9487 } |
9488 } |
9488 } |
9489 } |
9489 } |
9490 } |
9490 } |
9491 |
9491 |
9492 if (__pix != 0) { |
9492 if (__pix != 0) { |
9493 *__dstPtr = __pix; |
9493 *__dstPtr = __pix; |
9494 } |
9494 } |
9495 __dstPtr++; |
9495 __dstPtr++; |
9496 } |
9496 } |
9497 } |
9497 } |
9498 break; |
9498 break; |
9499 |
9499 |
9500 case 1: |
9500 case 1: |
9501 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9501 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9502 double __pY, __sinPY, __cosPY; |
9502 double __pY, __sinPY, __cosPY; |
9503 #ifdef EARLY_OUT |
9503 #ifdef EARLY_OUT |
9504 int didFetchInRow = 0; |
9504 int didFetchInRow = 0; |
9505 #endif |
9505 #endif |
9506 __pY = (double)(__dstY + __minY); |
9506 __pY = (double)(__dstY + __minY); |
9507 |
9507 |
9508 __sinPY = __sin * __pY; |
9508 __sinPY = __sin * __pY; |
9509 __cosPY = __cos * __pY; |
9509 __cosPY = __cos * __pY; |
9510 |
9510 |
9511 __dstPtr = __dstRowPtr; |
9511 __dstPtr = __dstRowPtr; |
9512 __dstMask = 0x80; |
9512 __dstMask = 0x80; |
9513 __dstRowPtr += __dstBytesPerRow; |
9513 __dstRowPtr += __dstBytesPerRow; |
9514 |
9514 |
9515 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9515 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9516 double __pX, __nX; |
9516 double __pX, __nX; |
9517 int __pix; |
9517 int __pix; |
9518 |
9518 |
9519 /* translate X in destination (center to 0/0) */ |
9519 /* translate X in destination (center to 0/0) */ |
9520 __pX = (double)(__dstX + __minX); |
9520 __pX = (double)(__dstX + __minX); |
9521 /* rotate X */ |
9521 /* rotate X */ |
9522 __nX = (__cos * __pX) - __sinPY; |
9522 __nX = (__cos * __pX) - __sinPY; |
9523 |
9523 |
9524 /* translate X in source (origin to 0/0) */ |
9524 /* translate X in source (origin to 0/0) */ |
9525 __nX = __nX + __halfW + 0.5; |
9525 __nX = __nX + __halfW + 0.5; |
9526 |
9526 |
9527 /* inside ? */ |
9527 /* inside ? */ |
9528 if (__nX < 0) { |
9528 if (__nX < 0) { |
9529 #ifdef EARLY_OUT |
9529 #ifdef EARLY_OUT |
9530 if (didFetchInRow) { |
9530 if (didFetchInRow) { |
9531 break; |
9531 break; |
9532 } |
9532 } |
9533 #endif |
9533 #endif |
9534 #ifdef FAST_ADVANCE |
9534 #ifdef FAST_ADVANCE |
9535 if (__blackPixel == 0) { |
9535 if (__blackPixel == 0) { |
9536 do { |
9536 do { |
9537 /* try advance by 8 pixels ... */ |
9537 /* try advance by 8 pixels ... */ |
9538 __dstX += 8; __dstPtr ++; |
9538 __dstX += 8; __dstPtr ++; |
9539 if (__dstX >= __newWidth) { |
9539 if (__dstX >= __newWidth) { |
9540 break; |
9540 break; |
9541 } |
9541 } |
9542 __pX = (double)(__dstX + __minX); |
9542 __pX = (double)(__dstX + __minX); |
9543 __nX = (__cos * __pX) - __sinPY; |
9543 __nX = (__cos * __pX) - __sinPY; |
9544 __nX = __nX + __halfW + 0.5; |
9544 __nX = __nX + __halfW + 0.5; |
9545 } while (__nX < 0); |
9545 } while (__nX < 0); |
9546 __dstX -= 8; __dstPtr--; |
9546 __dstX -= 8; __dstPtr--; |
9547 } |
9547 } |
9548 #endif |
9548 #endif |
9549 __pix = __blackPixel; |
9549 __pix = __blackPixel; |
9550 } else { |
9550 } else { |
9551 int __srcX; |
9551 int __srcX; |
9552 |
9552 |
9553 __srcX = (int)__nX; |
9553 __srcX = (int)__nX; |
9554 /* inside ? */ |
9554 /* inside ? */ |
9555 if (__srcX >= __width) { |
9555 if (__srcX >= __width) { |
9556 #ifdef EARLY_OUT |
9556 #ifdef EARLY_OUT |
9557 if (didFetchInRow) { |
9557 if (didFetchInRow) { |
9558 break; |
9558 break; |
9559 } |
9559 } |
9560 #endif |
9560 #endif |
9561 #ifdef FAST_ADVANCE2 |
9561 #ifdef FAST_ADVANCE2 |
9562 if (__blackPixel == 0) { |
9562 if (__blackPixel == 0) { |
9563 do { |
9563 do { |
9564 /* try advance by 8 pixels ... */ |
9564 /* try advance by 8 pixels ... */ |
9565 __dstX += 8; __dstPtr++; |
9565 __dstX += 8; __dstPtr++; |
9566 if (__dstX >= __newWidth) { |
9566 if (__dstX >= __newWidth) { |
9567 break; |
9567 break; |
9568 } |
9568 } |
9569 __pX = (double)(__dstX + __minX); |
9569 __pX = (double)(__dstX + __minX); |
9570 __nX = (__cos * __pX) - __sinPY; |
9570 __nX = (__cos * __pX) - __sinPY; |
9571 __nX = __nX + __halfW + 0.5; |
9571 __nX = __nX + __halfW + 0.5; |
9572 __srcX = (int)__nX; |
9572 __srcX = (int)__nX; |
9573 } while (__srcX >= __width); |
9573 } while (__srcX >= __width); |
9574 __dstX -= 8; __dstPtr--; |
9574 __dstX -= 8; __dstPtr--; |
9575 } |
9575 } |
9576 #endif |
9576 #endif |
9577 __pix = __blackPixel; |
9577 __pix = __blackPixel; |
9578 } else { |
9578 } else { |
9579 double __nY; |
9579 double __nY; |
9580 |
9580 |
9581 /* rotate Y */ |
9581 /* rotate Y */ |
9582 __nY = (__sin * __pX) + __cosPY; |
9582 __nY = (__sin * __pX) + __cosPY; |
9583 /* translate Y in source (origin to 0/0) */ |
9583 /* translate Y in source (origin to 0/0) */ |
9584 __nY = __nY + __halfH + 0.5; |
9584 __nY = __nY + __halfH + 0.5; |
9585 |
9585 |
9586 /* inside ? */ |
9586 /* inside ? */ |
9587 if (__nY < 0) { |
9587 if (__nY < 0) { |
9588 #ifdef EARLY_OUT |
9588 #ifdef EARLY_OUT |
9589 if (didFetchInRow) { |
9589 if (didFetchInRow) { |
9590 break; |
9590 break; |
9591 } |
9591 } |
9592 #endif |
9592 #endif |
9593 #ifdef FAST_ADVANCE2 |
9593 #ifdef FAST_ADVANCE2 |
9594 if (__blackPixel == 0) { |
9594 if (__blackPixel == 0) { |
9595 do { |
9595 do { |
9596 /* try advance by 8 pixels ... */ |
9596 /* try advance by 8 pixels ... */ |
9597 __dstX += 8; __dstPtr++; |
9597 __dstX += 8; __dstPtr++; |
9598 if (__dstX >= __newWidth) { |
9598 if (__dstX >= __newWidth) { |
9599 break; |
9599 break; |
9600 } |
9600 } |
9601 __pX = (double)(__dstX + __minX); |
9601 __pX = (double)(__dstX + __minX); |
9602 __nY = (__sin * __pX) + __cosPY; |
9602 __nY = (__sin * __pX) + __cosPY; |
9603 __nY = __nY + __halfH + 0.5; |
9603 __nY = __nY + __halfH + 0.5; |
9604 } while (__nY < 0); |
9604 } while (__nY < 0); |
9605 __dstX -= 8; __dstPtr--; |
9605 __dstX -= 8; __dstPtr--; |
9606 } |
9606 } |
9607 #endif |
9607 #endif |
9608 __pix = __blackPixel; |
9608 __pix = __blackPixel; |
9609 } else { |
9609 } else { |
9610 int __srcY; |
9610 int __srcY; |
9611 |
9611 |
9612 __srcY = (int)__nY; |
9612 __srcY = (int)__nY; |
9613 /* inside ? */ |
9613 /* inside ? */ |
9614 if (__srcY >= __height) { |
9614 if (__srcY >= __height) { |
9615 #ifdef EARLY_OUT |
9615 #ifdef EARLY_OUT |
9616 if (didFetchInRow) { |
9616 if (didFetchInRow) { |
9617 break; |
9617 break; |
9618 } |
9618 } |
9619 #endif |
9619 #endif |
9620 #ifdef FAST_ADVANCE |
9620 #ifdef FAST_ADVANCE |
9621 if (__blackPixel == 0) { |
9621 if (__blackPixel == 0) { |
9622 do { |
9622 do { |
9623 /* try advance by 8 pixels ... */ |
9623 /* try advance by 8 pixels ... */ |
9624 __dstX += 8; __dstPtr++; |
9624 __dstX += 8; __dstPtr++; |
9625 if (__dstX >= __newWidth) { |
9625 if (__dstX >= __newWidth) { |
9626 break; |
9626 break; |
9627 } |
9627 } |
9628 __pX = (double)(__dstX + __minX); |
9628 __pX = (double)(__dstX + __minX); |
9629 __nY = (__sin * __pX) + __cosPY; |
9629 __nY = (__sin * __pX) + __cosPY; |
9630 __nY = __nY + __halfH + 0.5; |
9630 __nY = __nY + __halfH + 0.5; |
9631 __srcY = (int)__nY; |
9631 __srcY = (int)__nY; |
9632 } while (__srcY >= __height); |
9632 } while (__srcY >= __height); |
9633 __dstX -= 8; __dstPtr--; |
9633 __dstX -= 8; __dstPtr--; |
9634 } |
9634 } |
9635 #endif |
9635 #endif |
9636 __pix = __blackPixel; |
9636 __pix = __blackPixel; |
9637 } else { |
9637 } else { |
9638 /* fetch source pixel */ |
9638 /* fetch source pixel */ |
9639 |
9639 |
9640 int idx, pV; |
9640 int idx, pV; |
9641 #ifdef EARLY_OUT |
9641 #ifdef EARLY_OUT |
9642 didFetchInRow = 1; |
9642 didFetchInRow = 1; |
9643 #endif |
9643 #endif |
9644 idx = __srcY * __srcBytesPerRow + (__srcX >> 3); |
9644 idx = __srcY * __srcBytesPerRow + (__srcX >> 3); |
9645 if ((unsigned)idx < __nSrcBytes) { |
9645 if ((unsigned)idx < __nSrcBytes) { |
9646 pV = __srcBytes[idx]; |
9646 pV = __srcBytes[idx]; |
9647 __pix = (pV & (0x80 >> (__srcX & 7))) ? 1 : 0; |
9647 __pix = (pV & (0x80 >> (__srcX & 7))) ? 1 : 0; |
9648 } else { |
9648 } else { |
9649 __pix = __blackPixel; |
9649 __pix = __blackPixel; |
9650 } |
9650 } |
9651 } |
9651 } |
9652 } |
9652 } |
9653 } |
9653 } |
9654 } |
9654 } |
9655 |
9655 |
9656 /* store pixel */ |
9656 /* store pixel */ |
9657 if (__pix != 0) { |
9657 if (__pix != 0) { |
9658 *__dstPtr |= __dstMask; |
9658 *__dstPtr |= __dstMask; |
9659 } |
9659 } |
9660 __dstMask >>= 1; |
9660 __dstMask >>= 1; |
9661 if (__dstMask == 0) { |
9661 if (__dstMask == 0) { |
9662 __dstMask = 0x80; |
9662 __dstMask = 0x80; |
9663 __dstPtr++; |
9663 __dstPtr++; |
9664 } |
9664 } |
9665 } |
9665 } |
9666 } |
9666 } |
9667 break; |
9667 break; |
9668 |
9668 |
9669 case 24: |
9669 case 24: |
9670 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9670 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9671 double __pY, __sinPY, __cosPY; |
9671 double __pY, __sinPY, __cosPY; |
9672 #ifdef EARLY_OUT |
9672 #ifdef EARLY_OUT |
9673 int didFetchInRow = 0; |
9673 int didFetchInRow = 0; |
9674 #endif |
9674 #endif |
9675 __pY = (double)(__dstY + __minY); |
9675 __pY = (double)(__dstY + __minY); |
9676 |
9676 |
9677 __sinPY = __sin * __pY; |
9677 __sinPY = __sin * __pY; |
9678 __cosPY = __cos * __pY; |
9678 __cosPY = __cos * __pY; |
9679 |
9679 |
9680 __dstPtr = __dstRowPtr; |
9680 __dstPtr = __dstRowPtr; |
9681 __dstRowPtr += __dstBytesPerRow; |
9681 __dstRowPtr += __dstBytesPerRow; |
9682 |
9682 |
9683 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9683 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9684 double __pX, __nX; |
9684 double __pX, __nX; |
9685 unsigned __pix; |
9685 unsigned __pix; |
9686 |
9686 |
9687 /* translate X in destination (center to 0/0) */ |
9687 /* translate X in destination (center to 0/0) */ |
9688 __pX = (double)(__dstX + __minX); |
9688 __pX = (double)(__dstX + __minX); |
9689 /* rotate X */ |
9689 /* rotate X */ |
9690 __nX = (__cos * __pX) - __sinPY; |
9690 __nX = (__cos * __pX) - __sinPY; |
9691 |
9691 |
9692 /* translate X in source (origin to 0/0) */ |
9692 /* translate X in source (origin to 0/0) */ |
9693 __nX = __nX + __halfW + 0.5; |
9693 __nX = __nX + __halfW + 0.5; |
9694 |
9694 |
9695 /* inside ? */ |
9695 /* inside ? */ |
9696 if (__nX < 0) { |
9696 if (__nX < 0) { |
9697 #ifdef EARLY_OUT |
9697 #ifdef EARLY_OUT |
9698 if (didFetchInRow) { |
9698 if (didFetchInRow) { |
9699 break; |
9699 break; |
9700 } |
9700 } |
9701 #endif |
9701 #endif |
9702 __pix = __blackPixel; |
9702 __pix = __blackPixel; |
9703 } else { |
9703 } else { |
9704 int __srcX; |
9704 int __srcX; |
9705 |
9705 |
9706 __srcX = (int)__nX; |
9706 __srcX = (int)__nX; |
9707 /* inside ? */ |
9707 /* inside ? */ |
9708 if (__srcX >= __width) { |
9708 if (__srcX >= __width) { |
9709 #ifdef EARLY_OUT |
9709 #ifdef EARLY_OUT |
9710 if (didFetchInRow) { |
9710 if (didFetchInRow) { |
9711 break; |
9711 break; |
9712 } |
9712 } |
9713 #endif |
9713 #endif |
9714 __pix = __blackPixel; |
9714 __pix = __blackPixel; |
9715 } else { |
9715 } else { |
9716 double __nY; |
9716 double __nY; |
9717 |
9717 |
9718 /* rotate Y */ |
9718 /* rotate Y */ |
9719 __nY = (__sin * __pX) + __cosPY; |
9719 __nY = (__sin * __pX) + __cosPY; |
9720 /* translate Y in source (origin to 0/0) */ |
9720 /* translate Y in source (origin to 0/0) */ |
9721 __nY = __nY + __halfH + 0.5; |
9721 __nY = __nY + __halfH + 0.5; |
9722 |
9722 |
9723 /* inside ? */ |
9723 /* inside ? */ |
9724 if (__nY < 0) { |
9724 if (__nY < 0) { |
9725 #ifdef EARLY_OUT |
9725 #ifdef EARLY_OUT |
9726 if (didFetchInRow) { |
9726 if (didFetchInRow) { |
9727 break; |
9727 break; |
9728 } |
9728 } |
9729 #endif |
9729 #endif |
9730 __pix = __blackPixel; |
9730 __pix = __blackPixel; |
9731 } else { |
9731 } else { |
9732 int __srcY; |
9732 int __srcY; |
9733 |
9733 |
9734 __srcY = (int)__nY; |
9734 __srcY = (int)__nY; |
9735 /* inside ? */ |
9735 /* inside ? */ |
9736 if (__srcY >= __height) { |
9736 if (__srcY >= __height) { |
9737 #ifdef EARLY_OUT |
9737 #ifdef EARLY_OUT |
9738 if (didFetchInRow) { |
9738 if (didFetchInRow) { |
9739 break; |
9739 break; |
9740 } |
9740 } |
9741 #endif |
9741 #endif |
9742 __pix = __blackPixel; |
9742 __pix = __blackPixel; |
9743 } else { |
9743 } else { |
9744 /* fetch source pixel */ |
9744 /* fetch source pixel */ |
9745 |
9745 |
9746 int idx; |
9746 int idx; |
9747 #ifdef EARLY_OUT |
9747 #ifdef EARLY_OUT |
9748 didFetchInRow = 1; |
9748 didFetchInRow = 1; |
9749 #endif |
9749 #endif |
9750 idx = __srcY * __srcBytesPerRow + __srcX + __srcX + __srcX; |
9750 idx = __srcY * __srcBytesPerRow + __srcX + __srcX + __srcX; |
9751 if ((unsigned)idx < __nSrcBytes) { |
9751 if ((unsigned)idx < __nSrcBytes) { |
9752 __pix = __srcBytes[idx]; |
9752 __pix = __srcBytes[idx]; |
9753 __pix = (__pix<<8) | __srcBytes[idx+1]; |
9753 __pix = (__pix<<8) | __srcBytes[idx+1]; |
9754 __pix = (__pix<<8) | __srcBytes[idx+2]; |
9754 __pix = (__pix<<8) | __srcBytes[idx+2]; |
9755 } else { |
9755 } else { |
9756 __pix = __blackPixel; |
9756 __pix = __blackPixel; |
9757 } |
9757 } |
9758 } |
9758 } |
9759 } |
9759 } |
9760 } |
9760 } |
9761 } |
9761 } |
9762 |
9762 |
9763 /* store pixel */ |
9763 /* store pixel */ |
9764 if (__pix != 0) { |
9764 if (__pix != 0) { |
9765 __dstPtr[0] = (__pix >> 16 & 0xFF); |
9765 __dstPtr[0] = (__pix >> 16 & 0xFF); |
9766 __dstPtr[1] = (__pix >> 8) & 0xFF; |
9766 __dstPtr[1] = (__pix >> 8) & 0xFF; |
9767 __dstPtr[2] = __pix & 0xFF; |
9767 __dstPtr[2] = __pix & 0xFF; |
9768 } |
9768 } |
9769 __dstPtr += 3; |
9769 __dstPtr += 3; |
9770 } |
9770 } |
9771 } |
9771 } |
9772 break; |
9772 break; |
9773 |
9773 |
9774 default: |
9774 default: |
9775 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9775 for (__dstY = 0; __dstY < __newHeight; __dstY++) { |
9776 double __pY, __sinPY, __cosPY; |
9776 double __pY, __sinPY, __cosPY; |
9777 #ifdef EARLY_OUT |
9777 #ifdef EARLY_OUT |
9778 int didFetchInRow = 0; |
9778 int didFetchInRow = 0; |
9779 #endif |
9779 #endif |
9780 __pY = (double)(__dstY + __minY); |
9780 __pY = (double)(__dstY + __minY); |
9781 |
9781 |
9782 __sinPY = __sin * __pY; |
9782 __sinPY = __sin * __pY; |
9783 __cosPY = __cos * __pY; |
9783 __cosPY = __cos * __pY; |
9784 |
9784 |
9785 __dstPtr = __dstRowPtr; |
9785 __dstPtr = __dstRowPtr; |
9786 __dstMask = 0x80; |
9786 __dstMask = 0x80; |
9787 __dstRowPtr += __dstBytesPerRow; |
9787 __dstRowPtr += __dstBytesPerRow; |
9788 |
9788 |
9789 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9789 for (__dstX = 0; __dstX < __newWidth; __dstX++) { |
9790 double __pX, __nX; |
9790 double __pX, __nX; |
9791 OBJ __pix; |
9791 OBJ __pix; |
9792 |
9792 |
9793 /* translate X in destination (center to 0/0) */ |
9793 /* translate X in destination (center to 0/0) */ |
9794 __pX = (double)(__dstX + __minX); |
9794 __pX = (double)(__dstX + __minX); |
9795 /* rotate X */ |
9795 /* rotate X */ |
9796 __nX = (__cos * __pX) - __sinPY; |
9796 __nX = (__cos * __pX) - __sinPY; |
9797 |
9797 |
9798 /* translate X in source (origin to 0/0) */ |
9798 /* translate X in source (origin to 0/0) */ |
9799 __nX = __nX + __halfW + 0.5; |
9799 __nX = __nX + __halfW + 0.5; |
9800 |
9800 |
9801 /* inside ? */ |
9801 /* inside ? */ |
9802 if (__nX < 0) { |
9802 if (__nX < 0) { |
9803 #ifdef EARLY_OUT |
9803 #ifdef EARLY_OUT |
9804 if (didFetchInRow) { |
9804 if (didFetchInRow) { |
9805 break; |
9805 break; |
9806 } |
9806 } |
9807 #endif |
9807 #endif |
9808 __pix = blackPixel; |
9808 __pix = blackPixel; |
9809 } else { |
9809 } else { |
9810 int __srcX; |
9810 int __srcX; |
9811 |
9811 |
9812 __srcX = (int)__nX; |
9812 __srcX = (int)__nX; |
9813 /* inside ? */ |
9813 /* inside ? */ |
9814 if (__srcX >= __width) { |
9814 if (__srcX >= __width) { |
9815 #ifdef EARLY_OUT |
9815 #ifdef EARLY_OUT |
9816 if (didFetchInRow) { |
9816 if (didFetchInRow) { |
9817 break; |
9817 break; |
9818 } |
9818 } |
9819 #endif |
9819 #endif |
9820 __pix = blackPixel; |
9820 __pix = blackPixel; |
9821 } else { |
9821 } else { |
9822 double __nY; |
9822 double __nY; |
9823 |
9823 |
9824 /* rotate Y */ |
9824 /* rotate Y */ |
9825 __nY = (__sin * __pX) + __cosPY; |
9825 __nY = (__sin * __pX) + __cosPY; |
9826 /* translate Y in source (origin to 0/0) */ |
9826 /* translate Y in source (origin to 0/0) */ |
9827 __nY = __nY + __halfH + 0.5; |
9827 __nY = __nY + __halfH + 0.5; |
9828 |
9828 |
9829 /* inside ? */ |
9829 /* inside ? */ |
9830 if (__nY < 0) { |
9830 if (__nY < 0) { |
9831 #ifdef EARLY_OUT |
9831 #ifdef EARLY_OUT |
9832 if (didFetchInRow) { |
9832 if (didFetchInRow) { |
9833 break; |
9833 break; |
9834 } |
9834 } |
9835 #endif |
9835 #endif |
9836 __pix = blackPixel; |
9836 __pix = blackPixel; |
9837 } else { |
9837 } else { |
9838 int __srcY; |
9838 int __srcY; |
9839 |
9839 |
9840 __srcY = (int)__nY; |
9840 __srcY = (int)__nY; |
9841 /* inside ? */ |
9841 /* inside ? */ |
9842 if (__srcY >= __height) { |
9842 if (__srcY >= __height) { |
9843 #ifdef EARLY_OUT |
9843 #ifdef EARLY_OUT |
9844 if (didFetchInRow) { |
9844 if (didFetchInRow) { |
9845 break; |
9845 break; |
9846 } |
9846 } |
9847 #endif |
9847 #endif |
9848 __pix = blackPixel; |
9848 __pix = blackPixel; |
9849 } else { |
9849 } else { |
9850 /* fetch source pixel */ |
9850 /* fetch source pixel */ |
9851 |
9851 |
9852 static struct inlineCache valAt = _ILC2; |
9852 static struct inlineCache valAt = _ILC2; |
9853 #ifdef EARLY_OUT |
9853 #ifdef EARLY_OUT |
9854 didFetchInRow = 1; |
9854 didFetchInRow = 1; |
9855 #endif |
9855 #endif |
9856 __pix = (*valAt.ilc_func)(self, |
9856 __pix = (*valAt.ilc_func)(self, |
9857 @symbol(pixelAtX:y:), |
9857 @symbol(pixelAtX:y:), |
9858 nil, &valAt, |
9858 nil, &valAt, |
9859 __MKSMALLINT(__srcX), |
9859 __MKSMALLINT(__srcX), |
9860 __MKSMALLINT(__srcY)); |
9860 __MKSMALLINT(__srcY)); |
9861 } |
9861 } |
9862 } |
9862 } |
9863 } |
9863 } |
9864 } |
9864 } |
9865 |
9865 |
9866 /* store pixel */ |
9866 /* store pixel */ |
9867 { |
9867 { |
9868 static struct inlineCache atPutVal = _ILC3; |
9868 static struct inlineCache atPutVal = _ILC3; |
9869 |
9869 |
9870 if (__pix != __MKSMALLINT(0)) { |
9870 if (__pix != __MKSMALLINT(0)) { |
9871 (*atPutVal.ilc_func)(newImage, |
9871 (*atPutVal.ilc_func)(newImage, |
9872 @symbol(pixelAtX:y:put:), |
9872 @symbol(pixelAtX:y:put:), |
9873 nil, &atPutVal, |
9873 nil, &atPutVal, |
9874 __MKSMALLINT(__dstX), |
9874 __MKSMALLINT(__dstX), |
9875 __MKSMALLINT(__dstY), |
9875 __MKSMALLINT(__dstY), |
9876 __pix |
9876 __pix |
9877 ); |
9877 ); |
9878 } |
9878 } |
9879 } |
9879 } |
9880 } |
9880 } |
9881 } |
9881 } |
9882 break; |
9882 break; |
9883 } |
9883 } |
9884 |
9884 |
9885 bad = false; |
9885 bad = false; |
9886 } |
9886 } |
9887 %}. |
9887 %}. |
9888 |
9888 |
9889 bad ifTrue:[ |
9889 bad ifTrue:[ |
9890 "/ should not happen |
9890 "/ should not happen |
9891 self primitiveFailed |
9891 self primitiveFailed |
9892 |
9892 |
9893 "/ sinRot := radians negated sin. |
9893 "/ sinRot := radians negated sin. |
9894 "/ cosRot := radians negated cos. |
9894 "/ cosRot := radians negated cos. |
9895 "/ |
9895 "/ |
9896 "/ 0 to:newHeight-1 do:[:dstY | |
9896 "/ 0 to:newHeight-1 do:[:dstY | |
9917 "/ |
9917 "/ |
9918 "/ "/ inside ? |
9918 "/ "/ inside ? |
9919 "/ (srcY >= 0 and:[srcY < height]) ifTrue:[ |
9919 "/ (srcY >= 0 and:[srcY < height]) ifTrue:[ |
9920 "/ pix := self pixelAtX:srcX y:srcY |
9920 "/ pix := self pixelAtX:srcX y:srcY |
9921 "/ ] ifFalse:[ |
9921 "/ ] ifFalse:[ |
9922 "/ pix := blackPixel. |
9922 "/ pix := blackPixel. |
9923 "/ ]. |
9923 "/ ]. |
9924 "/ ] ifFalse:[ |
9924 "/ ] ifFalse:[ |
9925 "/ pix := blackPixel. |
9925 "/ pix := blackPixel. |
9926 "/ ]. |
9926 "/ ]. |
9927 "/ pix ~~ blackPixel ifTrue:[ |
9927 "/ pix ~~ blackPixel ifTrue:[ |
9928 "/ newImage pixelAtX:dstX y:dstY put:pix. |
9928 "/ newImage pixelAtX:dstX y:dstY put:pix. |
9929 "/ ] |
9929 "/ ] |
9930 "/ ]. |
9930 "/ ]. |
9931 "/ ]. |
9931 "/ ]. |
9932 ]. |
9932 ]. |
9933 |
9933 |
9953 " |
9953 " |
9954 |i| |
9954 |i| |
9955 |
9955 |
9956 i := Smalltalk imageFromFileNamed:'bitmaps/gifImages/garfield.gif' inPackage:'stx:goodies'. |
9956 i := Smalltalk imageFromFileNamed:'bitmaps/gifImages/garfield.gif' inPackage:'stx:goodies'. |
9957 Transcript showCR:( |
9957 Transcript showCR:( |
9958 Time millisecondsToRun:[ |
9958 Time millisecondsToRun:[ |
9959 i rotated:45. |
9959 i rotated:45. |
9960 ] |
9960 ] |
9961 ). |
9961 ). |
9962 " |
9962 " |
9963 " |
9963 " |
9964 |v i rI rot| |
9964 |v i rI rot| |
9965 |
9965 |
9966 i := Smalltalk imageFromFileNamed:'bitmaps/xpmBitmaps/misc_icons/BOOK.xpm' inPackage:'stx:goodies'. |
9966 i := Smalltalk imageFromFileNamed:'bitmaps/xpmBitmaps/misc_icons/BOOK.xpm' inPackage:'stx:goodies'. |
9967 v := View new extent:(i width max:100)@(i height max:100). |
9967 v := View new extent:(i width max:100)@(i height max:100). |
9968 v openAndWait. |
9968 v openAndWait. |
9969 rot := 0. |
9969 rot := 0. |
9970 [true] whileTrue:[ |
9970 [true] whileTrue:[ |
9971 rI := i rotated:rot. |
9971 rI := i rotated:rot. |
9972 rI := rI onDevice:v device. |
9972 rI := rI onDevice:v device. |
9973 v clear. |
9973 v clear. |
9974 v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2). |
9974 v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2). |
9975 rot := rot + 5. |
9975 rot := rot + 5. |
9976 rI close. |
9976 rI close. |
9977 ] |
9977 ] |
9978 " |
9978 " |
9979 " |
9979 " |
9980 |v i rI rot| |
9980 |v i rI rot| |
9981 |
9981 |
9982 i := Smalltalk imageFromFileNamed:'bitmaps/gifImages/claus.gif' inPackage:'stx:goodies'. |
9982 i := Smalltalk imageFromFileNamed:'bitmaps/gifImages/claus.gif' inPackage:'stx:goodies'. |
9983 v := View new extent:400@400. |
9983 v := View new extent:400@400. |
9984 v openAndWait. |
9984 v openAndWait. |
9985 rot := 0. |
9985 rot := 0. |
9986 [true] whileTrue:[ |
9986 [true] whileTrue:[ |
9987 rI := i rotated:rot. |
9987 rI := i rotated:rot. |
9988 rI := rI onDevice:v device. |
9988 rI := rI onDevice:v device. |
9989 v clear. |
9989 v clear. |
9990 v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2). |
9990 v displayForm:rI x:v width//2-(rI width//2) y:v height//2-(rI height // 2). |
9991 rot := rot + 5. |
9991 rot := rot + 5. |
9992 rI close. |
9992 rI close. |
9993 ] |
9993 ] |
9994 " |
9994 " |
9995 |
9995 |
9996 "Modified: 22.4.1997 / 17:36:37 / cg" |
9996 "Modified: 22.4.1997 / 17:36:37 / cg" |
9997 ! |
9997 ! |
10000 "return a new image which is slightly brighter than the receiver. |
10000 "return a new image which is slightly brighter than the receiver. |
10001 The receiver must be a palette image (currently). |
10001 The receiver must be a palette image (currently). |
10002 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
10002 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
10003 CAVEAT: Need an argument, which specifies by how much it should be lighter." |
10003 CAVEAT: Need an argument, which specifies by how much it should be lighter." |
10004 |
10004 |
10005 ^ self |
10005 ^ self |
10006 copyWithColorMapProcessing:[:clr | clr lightened] |
10006 copyWithColorMapProcessing:[:clr | clr lightened] |
10007 |
10007 |
10008 " |
10008 " |
10009 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
10009 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
10010 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') lightened inspect |
10010 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') lightened inspect |
10011 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') darkened inspect |
10011 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') darkened inspect |
10059 mask notNil ifTrue:[ |
10059 mask notNil ifTrue:[ |
10060 newMask := (mask magnifiedBy:scalePoint) |
10060 newMask := (mask magnifiedBy:scalePoint) |
10061 ]. |
10061 ]. |
10062 |
10062 |
10063 newImage := self species new. |
10063 newImage := self species new. |
10064 newImage |
10064 newImage |
10065 width:newWidth |
10065 width:newWidth |
10066 height:newHeight |
10066 height:newHeight |
10067 photometric:photometric |
10067 photometric:photometric |
10068 samplesPerPixel:samplesPerPixel |
10068 samplesPerPixel:samplesPerPixel |
10069 bitsPerSample:bitsPerSample |
10069 bitsPerSample:bitsPerSample |
10070 colorMap:colorMap copy |
10070 colorMap:colorMap copy |
10071 bits:newBits |
10071 bits:newBits |
10072 mask:newMask. |
10072 mask:newMask. |
10073 |
10073 |
10074 mX = 1 ifTrue:[ |
10074 mX = 1 ifTrue:[ |
10076 srcOffset := 1. |
10076 srcOffset := 1. |
10077 dstOffset := 1. |
10077 dstOffset := 1. |
10078 |
10078 |
10079 1 to:h do:[:row | |
10079 1 to:h do:[:row | |
10080 1 to:magY do:[:i | |
10080 1 to:magY do:[:i | |
10081 newBits replaceFrom:dstOffset |
10081 newBits replaceFrom:dstOffset |
10082 to:(dstOffset + oldBytesPerRow - 1) |
10082 to:(dstOffset + oldBytesPerRow - 1) |
10083 with:bytes |
10083 with:bytes |
10084 startingAt:srcOffset. |
10084 startingAt:srcOffset. |
10085 dstOffset := dstOffset + newBytesPerRow |
10085 dstOffset := dstOffset + newBytesPerRow |
10086 ]. |
10086 ]. |
10087 srcOffset := srcOffset + oldBytesPerRow. |
10087 srcOffset := srcOffset + oldBytesPerRow. |
10088 ]. |
10088 ]. |
10090 "expand cols" |
10090 "expand cols" |
10091 (mX > 1) ifTrue:[ |
10091 (mX > 1) ifTrue:[ |
10092 dstOffset := 1. |
10092 dstOffset := 1. |
10093 srcOffset := 1. |
10093 srcOffset := 1. |
10094 1 to:h do:[:row | |
10094 1 to:h do:[:row | |
10095 self magnifyRowFrom:bytes |
10095 self magnifyRowFrom:bytes |
10096 offset:srcOffset |
10096 offset:srcOffset |
10097 into:newBits |
10097 into:newBits |
10098 offset:dstOffset |
10098 offset:dstOffset |
10099 factor:mX. |
10099 factor:mX. |
10100 |
10100 |
10101 first := dstOffset. |
10101 first := dstOffset. |
10102 dstOffset := dstOffset + newBytesPerRow. |
10102 dstOffset := dstOffset + newBytesPerRow. |
10103 " and copy for row expansion " |
10103 " and copy for row expansion " |
10104 2 to:magY do:[:i | |
10104 2 to:magY do:[:i | |
10105 newBits replaceFrom:dstOffset |
10105 newBits replaceFrom:dstOffset |
10106 to:(dstOffset + newBytesPerRow - 1) |
10106 to:(dstOffset + newBytesPerRow - 1) |
10107 with:newBits |
10107 with:newBits |
10108 startingAt:first. |
10108 startingAt:first. |
10109 dstOffset := dstOffset + newBytesPerRow |
10109 dstOffset := dstOffset + newBytesPerRow |
10110 ]. |
10110 ]. |
10111 srcOffset := srcOffset + oldBytesPerRow. |
10111 srcOffset := srcOffset + oldBytesPerRow. |
10112 ]. |
10112 ]. |
10119 " |
10119 " |
10120 |
10120 |
10121 "Modified: 24.4.1997 / 18:32:04 / cg" |
10121 "Modified: 24.4.1997 / 18:32:04 / cg" |
10122 ! |
10122 ! |
10123 |
10123 |
10124 magnifiedPreservingRatioTo:anExtent |
10124 magnifiedPreservingRatioTo:anExtent |
10125 "return a new image magnified to fit into anExtent, |
10125 "return a new image magnified to fit into anExtent, |
10126 preserving the receivers width/height ratio. |
10126 preserving the receivers width/height ratio. |
10127 (i.e. not distorting the image). |
10127 (i.e. not distorting the image). |
10128 See also #magnifiedTo: and #magnifiedBy:" |
10128 See also #magnifiedTo: and #magnifiedBy:" |
10129 |
10129 |
10142 " |
10142 " |
10143 |
10143 |
10144 "Modified: 22.4.1997 / 12:33:46 / cg" |
10144 "Modified: 22.4.1997 / 12:33:46 / cg" |
10145 ! |
10145 ! |
10146 |
10146 |
10147 magnifiedTo:anExtent |
10147 magnifiedTo:anExtent |
10148 "return a new image magnified to have the size specified by extent. |
10148 "return a new image magnified to have the size specified by extent. |
10149 This may distort the image if the arguments ratio is not the images ratio. |
10149 This may distort the image if the arguments ratio is not the images ratio. |
10150 See also #magnifiedPreservingRatioTo: and #magnifiedBy:" |
10150 See also #magnifiedPreservingRatioTo: and #magnifiedBy:" |
10151 |
10151 |
10152 ^ self magnifiedBy:(anExtent / self extent) |
10152 ^ self magnifiedBy:(anExtent / self extent) |
10159 ((Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') magnifiedPreservingRatioTo:100@100) |
10159 ((Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') magnifiedPreservingRatioTo:100@100) |
10160 " |
10160 " |
10161 ! |
10161 ! |
10162 |
10162 |
10163 mixed:amount with:aColor |
10163 mixed:amount with:aColor |
10164 "return a new image which is blended with some color; |
10164 "return a new image which is blended with some color; |
10165 amount determines how much of the blending color is applied (0..) |
10165 amount determines how much of the blending color is applied (0..) |
10166 where 0 means: blending color pure. |
10166 where 0 means: blending color pure. |
10167 The receiver must be a palette image (currently). |
10167 The receiver must be a palette image (currently). |
10168 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
10168 CAVEAT: this only works with palette images (i.e. not for rgb or greyScale). |
10169 CAVEAT: Need an argument, which specifies by how much it should be lighter." |
10169 CAVEAT: Need an argument, which specifies by how much it should be lighter." |
10170 |
10170 |
10171 ^ self |
10171 ^ self |
10172 copyWithColorMapProcessing:[:clr | clr mixed:amount with:aColor] |
10172 copyWithColorMapProcessing:[:clr | clr mixed:amount with:aColor] |
10173 |
10173 |
10174 " |
10174 " |
10175 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
10175 (Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') inspect |
10176 ((Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') mixed:0.0 with:Color red) inspect |
10176 ((Smalltalk bitmapFromFileNamed:'gifImages/claus.gif' inPackage:'stx:goodies') mixed:0.0 with:Color red) inspect |
10203 ^ newImage |
10203 ^ newImage |
10204 ]. |
10204 ]. |
10205 ^ nil |
10205 ^ nil |
10206 ]. |
10206 ]. |
10207 |
10207 |
10208 ^ self |
10208 ^ self |
10209 copyWithColorMapProcessing:[:clr | |
10209 copyWithColorMapProcessing:[:clr | |
10210 |newColor| |
10210 |newColor| |
10211 |
10211 |
10212 newColor := Color |
10212 newColor := Color |
10213 redByte:(255 - clr redByte) |
10213 redByte:(255 - clr redByte) |
10214 greenByte:(255 - clr greenByte) |
10214 greenByte:(255 - clr greenByte) |
10297 |
10297 |
10298 |xMax yMax r g b nR nG nB clr pix map revMap n_clr n_pix mask anyChange |
10298 |xMax yMax r g b nR nG nB clr pix map revMap n_clr n_pix mask anyChange |
10299 newColors newColorArray newImage extMask extBits newPixelValue| |
10299 newColors newColorArray newImage extMask extBits newPixelValue| |
10300 |
10300 |
10301 numBits > 7 ifTrue:[ |
10301 numBits > 7 ifTrue:[ |
10302 ^ nil |
10302 ^ nil |
10303 ]. |
10303 ]. |
10304 mask := (16rFF bitShift:numBits) bitAnd:16rFF. |
10304 mask := (16rFF bitShift:numBits) bitAnd:16rFF. |
10305 extMask := (1 bitShift:numBits). |
10305 extMask := (1 bitShift:numBits). |
10306 extBits := extMask - 1. |
10306 extBits := extMask - 1. |
10307 |
10307 |
10319 newImage mask:(self mask copy). |
10319 newImage mask:(self mask copy). |
10320 |
10320 |
10321 xMax := width - 1. |
10321 xMax := width - 1. |
10322 yMax := height - 1. |
10322 yMax := height - 1. |
10323 |
10323 |
10324 newPixelValue := |
10324 newPixelValue := |
10325 [:image :pixelValue | |
10325 [:image :pixelValue | |
10326 |r g b nR nG nB| |
10326 |r g b nR nG nB| |
10327 |
10327 |
10328 r := image redBitsOf:pixelValue. |
10328 r := image redBitsOf:pixelValue. |
10329 g := image greenBitsOf:pixelValue. |
10329 g := image greenBitsOf:pixelValue. |
10330 b := image blueBitsOf:pixelValue. |
10330 b := image blueBitsOf:pixelValue. |
10331 nR := r bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10331 nR := r bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10332 nG := g bitAnd:mask. (nG bitAnd:extMask)~~0 ifTrue:[nG := nG bitOr:extBits]. |
10332 nG := g bitAnd:mask. (nG bitAnd:extMask)~~0 ifTrue:[nG := nG bitOr:extBits]. |
10333 nB := b bitAnd:mask. (nB bitAnd:extMask)~~0 ifTrue:[nB := nB bitOr:extBits]. |
10333 nB := b bitAnd:mask. (nB bitAnd:extMask)~~0 ifTrue:[nB := nB bitOr:extBits]. |
10334 image valueFromRedBits:nR greenBits:nG blueBits:nB. |
10334 image valueFromRedBits:nR greenBits:nG blueBits:nB. |
10335 ]. |
10335 ]. |
10336 |
10336 |
10337 |
10337 |
10338 photometric == #palette ifFalse:[ |
10338 photometric == #palette ifFalse:[ |
10339 "/ direct manipulation of the pixels |
10339 "/ direct manipulation of the pixels |
10340 0 to:yMax do:[:y | |
10340 0 to:yMax do:[:y | |
10341 0 to:xMax do:[:x | |
10341 0 to:xMax do:[:x | |
10342 pix := self pixelAtX:x y:y. |
10342 pix := self pixelAtX:x y:y. |
10343 n_pix := newPixelValue value:self value:pix. |
10343 n_pix := newPixelValue value:self value:pix. |
10344 n_pix ~= pix ifTrue:[ |
10344 n_pix ~= pix ifTrue:[ |
10345 newImage pixelAtX:x y:y put:n_pix. |
10345 newImage pixelAtX:x y:y put:n_pix. |
10346 anyChange := true. |
10346 anyChange := true. |
10347 ] |
10347 ] |
10348 ] |
10348 ] |
10349 ]. |
10349 ]. |
10350 anyChange ifFalse:[ |
10350 anyChange ifFalse:[ |
10351 ^ nil |
10351 ^ nil |
10352 ]. |
10352 ]. |
10353 ] ifTrue:[ |
10353 ] ifTrue:[ |
10354 "/ manipulate the colormap |
10354 "/ manipulate the colormap |
10355 0 to:yMax do:[:y | |
10355 0 to:yMax do:[:y | |
10356 0 to:xMax do:[:x | |
10356 0 to:xMax do:[:x | |
10357 pix := self pixelAtX:x y:y. |
10357 pix := self pixelAtX:x y:y. |
10358 (n_pix := map at:pix+1) isNil ifTrue:[ |
10358 (n_pix := map at:pix+1) isNil ifTrue:[ |
10359 clr := self colorAtX:x y:y. |
10359 clr := self colorAtX:x y:y. |
10360 |
10360 |
10361 r := clr redByte. |
10361 r := clr redByte. |
10362 g := clr greenByte. |
10362 g := clr greenByte. |
10363 b := clr blueByte. |
10363 b := clr blueByte. |
10364 nR := r bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10364 nR := r bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10365 nG := g bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10365 nG := g bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10366 nB := b bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10366 nB := b bitAnd:mask. (nR bitAnd:extMask)~~0 ifTrue:[nR := nR bitOr:extBits]. |
10367 n_clr := Color redByte:nR greenByte:nG blueByte:nB. |
10367 n_clr := Color redByte:nR greenByte:nG blueByte:nB. |
10368 (newColors includes:n_clr) ifFalse:[ |
10368 (newColors includes:n_clr) ifFalse:[ |
10369 newColors add:n_clr. |
10369 newColors add:n_clr. |
10370 newColorArray add:n_clr. |
10370 newColorArray add:n_clr. |
10371 revMap add:pix. |
10371 revMap add:pix. |
10372 map at:pix+1 put:(n_pix := revMap size - 1). |
10372 map at:pix+1 put:(n_pix := revMap size - 1). |
10373 ] ifTrue:[ |
10373 ] ifTrue:[ |
10374 "/ mhmh - multiple pixels mapped to the same color |
10374 "/ mhmh - multiple pixels mapped to the same color |
10375 n_pix := (newColorArray indexOf:n_clr) - 1. |
10375 n_pix := (newColorArray indexOf:n_clr) - 1. |
10376 map at:pix+1 put:n_pix. |
10376 map at:pix+1 put:n_pix. |
10377 ] |
10377 ] |
10378 ]. |
10378 ]. |
10379 newImage pixelAtX:x y:y put:n_pix. |
10379 newImage pixelAtX:x y:y put:n_pix. |
10380 ] |
10380 ] |
10381 ]. |
10381 ]. |
10382 revMap size == self colorMap size ifTrue:[ |
10382 revMap size == self colorMap size ifTrue:[ |
10383 revMap = (0 to:revMap size-1) ifTrue:[ |
10383 revMap = (0 to:revMap size-1) ifTrue:[ |
10384 ^ nil |
10384 ^ nil |
10385 ] |
10385 ] |
10386 ]. |
10386 ]. |
10387 |
10387 |
10388 newImage colorMap:(MappedPalette withColors:newColorArray). |
10388 newImage colorMap:(MappedPalette withColors:newColorArray). |
10389 ]. |
10389 ]. |
10390 |
10390 |
10391 ^ newImage |
10391 ^ newImage |
10392 ! |
10392 ! |
10393 |
10393 |
10396 on the pixel colors. |
10396 on the pixel colors. |
10397 Notice: this method is very slow - either apply pixel values |
10397 Notice: this method is very slow - either apply pixel values |
10398 (#withPixelFunctionAppliedToPixels:) or redefine this method in |
10398 (#withPixelFunctionAppliedToPixels:) or redefine this method in |
10399 a concrete subclass. |
10399 a concrete subclass. |
10400 (read `Beyond photography, by Gerard J. Holzmann; |
10400 (read `Beyond photography, by Gerard J. Holzmann; |
10401 ISBM 0-13-074410-7) |
10401 ISBM 0-13-074410-7) |
10402 See blurred / oilPointed as examples ...)" |
10402 See blurred / oilPointed as examples ...)" |
10403 |
10403 |
10404 |w "{Class: SmallInteger }" |
10404 |w "{Class: SmallInteger }" |
10405 h "{Class: SmallInteger }" |
10405 h "{Class: SmallInteger }" |
10406 newImage "newBits newBytesPerRow"| |
10406 newImage "newBits newBytesPerRow"| |
10419 |
10419 |
10420 w := width - 1. |
10420 w := width - 1. |
10421 h := height - 1. |
10421 h := height - 1. |
10422 |
10422 |
10423 0 to:h do:[:y | |
10423 0 to:h do:[:y | |
10424 0 to:w do:[:x | |
10424 0 to:w do:[:x | |
10425 newImage colorAtX:x y:y put:(pixelFunctionBlock |
10425 newImage colorAtX:x y:y put:(pixelFunctionBlock |
10426 value:self |
10426 value:self |
10427 value:(self colorAtX:x y:y) |
10427 value:(self colorAtX:x y:y) |
10428 value:x |
10428 value:x |
10429 value:y) |
10429 value:y) |
10430 ] |
10430 ] |
10431 ]. |
10431 ]. |
10432 ^ newImage |
10432 ^ newImage |
10433 |
10433 |
10434 "black out everything except for some rectangle: |
10434 "black out everything except for some rectangle: |
10435 |
10435 |
10438 i := Image fromFile:'goodies/bitmaps/gifImages/claus.gif'. |
10438 i := Image fromFile:'goodies/bitmaps/gifImages/claus.gif'. |
10439 i inspect. |
10439 i inspect. |
10440 |
10440 |
10441 black := Color black. |
10441 black := Color black. |
10442 (i withPixelFunctionApplied:[:oldImage :oldColor :x :y | |
10442 (i withPixelFunctionApplied:[:oldImage :oldColor :x :y | |
10443 ((x between:100 and:200) |
10443 ((x between:100 and:200) |
10444 and:[y between:100 and:200]) ifTrue:[ |
10444 and:[y between:100 and:200]) ifTrue:[ |
10445 oldColor |
10445 oldColor |
10446 ] ifFalse:[ |
10446 ] ifFalse:[ |
10447 black. |
10447 black. |
10448 ] |
10448 ] |
10449 ]) inspect. |
10449 ]) inspect. |
10450 " |
10450 " |
10451 "brighten a frame: |
10451 "brighten a frame: |
10452 |
10452 |
10453 |i black w h| |
10453 |i black w h| |
10454 |
10454 |
10456 i inspect. |
10456 i inspect. |
10457 |
10457 |
10458 w := i width. |
10458 w := i width. |
10459 h := i height. |
10459 h := i height. |
10460 (i withPixelFunctionApplied:[:oldImage :oldColor :x :y | |
10460 (i withPixelFunctionApplied:[:oldImage :oldColor :x :y | |
10461 ((x between:0 and:10) |
10461 ((x between:0 and:10) |
10462 or:[(y between:0 and:10) |
10462 or:[(y between:0 and:10) |
10463 or:[(x between:w-10 and:w) |
10463 or:[(x between:w-10 and:w) |
10464 or:[y between:h-10 and:h]]]) ifTrue:[ |
10464 or:[y between:h-10 and:h]]]) ifTrue:[ |
10465 oldColor lightened nearestIn:i colorMap |
10465 oldColor lightened nearestIn:i colorMap |
10466 ] ifFalse:[ |
10466 ] ifFalse:[ |
10467 oldColor. |
10467 oldColor. |
10468 ] |
10468 ] |
10469 ]) inspect. |
10469 ]) inspect. |
10470 " |
10470 " |
10471 |
10471 |
10472 "Modified: 24.4.1997 / 18:36:59 / cg" |
10472 "Modified: 24.4.1997 / 18:36:59 / cg" |
10473 ! |
10473 ! |
10474 |
10474 |
10477 on the pixel values. |
10477 on the pixel values. |
10478 (read `Beyond photography, by Gerard J. Holzmann; |
10478 (read `Beyond photography, by Gerard J. Holzmann; |
10479 ISBM 0-13-074410-7) |
10479 ISBM 0-13-074410-7) |
10480 See blurred / oilPointed as examples ...)" |
10480 See blurred / oilPointed as examples ...)" |
10481 |
10481 |
10482 ^ self |
10482 ^ self |
10483 withPixelFunctionAppliedToPixels:pixelFunctionBlock |
10483 withPixelFunctionAppliedToPixels:pixelFunctionBlock |
10484 in:(0@0 corner:width@height) |
10484 in:(0@0 corner:width@height) |
10485 |
10485 |
10486 "oil painting effect: |
10486 "oil painting effect: |
10487 |
10487 |
10488 |i w h| |
10488 |i w h| |
10588 |
10588 |
10589 withPixelFunctionAppliedToPixels:pixelFunctionBlock in:aRectangle |
10589 withPixelFunctionAppliedToPixels:pixelFunctionBlock in:aRectangle |
10590 "return a new image from the old one, by applying a pixel processor |
10590 "return a new image from the old one, by applying a pixel processor |
10591 on the pixel values. |
10591 on the pixel values. |
10592 (read `Beyond photography, by Gerard J. Holzmann; |
10592 (read `Beyond photography, by Gerard J. Holzmann; |
10593 ISBM 0-13-074410-7) |
10593 ISBM 0-13-074410-7) |
10594 See blurred / oilPointed as examples ...)" |
10594 See blurred / oilPointed as examples ...)" |
10595 |
10595 |
10596 |newImage "newBits newBytesPerRow"| |
10596 |newImage "newBits newBytesPerRow"| |
10597 |
10597 |
10598 newImage := self species new. |
10598 newImage := self species new. |
10617 i := Image fromFile:'goodies/bitmaps/gifImages/claus.gif'. |
10617 i := Image fromFile:'goodies/bitmaps/gifImages/claus.gif'. |
10618 i inspect. |
10618 i inspect. |
10619 w := i width - 1. |
10619 w := i width - 1. |
10620 h := i height - 1. |
10620 h := i height - 1. |
10621 (i withPixelFunctionAppliedToPixels:[:oldImage :oldPixel :x :y | |
10621 (i withPixelFunctionAppliedToPixels:[:oldImage :oldPixel :x :y | |
10622 |b p max xMin xMax yMin yMax| |
10622 |b p max xMin xMax yMin yMax| |
10623 |
10623 |
10624 b := Bag identityNew:10. |
10624 b := Bag identityNew:10. |
10625 xMin := x-3 max:0. |
10625 xMin := x-3 max:0. |
10626 xMax := x+3 min:w. |
10626 xMax := x+3 min:w. |
10627 yMin := y-3 max:0. |
10627 yMin := y-3 max:0. |
10628 yMax := y+3 min:h. |
10628 yMax := y+3 min:h. |
10629 xMin to:xMax do:[:tx| |
10629 xMin to:xMax do:[:tx| |
10630 yMin to:yMax do:[:ty| |
10630 yMin to:yMax do:[:ty| |
10631 b add:(oldImage pixelAtX:tx y:ty) |
10631 b add:(oldImage pixelAtX:tx y:ty) |
10632 ] |
10632 ] |
10633 ]. |
10633 ]. |
10634 max := 0. |
10634 max := 0. |
10635 b contents keysAndValuesDo:[:pixel :n | |
10635 b contents keysAndValuesDo:[:pixel :n | |
10636 n > max ifTrue:[ |
10636 n > max ifTrue:[ |
10637 p := pixel. |
10637 p := pixel. |
10638 max := n |
10638 max := n |
10639 ] |
10639 ] |
10640 ]. |
10640 ]. |
10641 p |
10641 p |
10642 ]) inspect. |
10642 ]) inspect. |
10643 " |
10643 " |
10644 |
10644 |
10645 "fisheye effect: |
10645 "fisheye effect: |
10646 |
10646 |
10647 |i w h w2 h2 R white| |
10647 |i w h w2 h2 R white| |
10653 w2 := w // 2. |
10653 w2 := w // 2. |
10654 h2 := h // 2. |
10654 h2 := h // 2. |
10655 R := w2. |
10655 R := w2. |
10656 white := i valueFromColor:Color white. |
10656 white := i valueFromColor:Color white. |
10657 (i withPixelFunctionAppliedToPixels:[:oldImage :oldPixel :x :y | |
10657 (i withPixelFunctionAppliedToPixels:[:oldImage :oldPixel :x :y | |
10658 |p r a nR nP nX nY| |
10658 |p r a nR nP nX nY| |
10659 |
10659 |
10660 p := (x-w2)@(y-h2). |
10660 p := (x-w2)@(y-h2). |
10661 r := p r. |
10661 r := p r. |
10662 a := p theta. |
10662 a := p theta. |
10663 nR := r * r / R. |
10663 nR := r * r / R. |
10664 nP := Point r:nR theta:a. |
10664 nP := Point r:nR theta:a. |
10665 nX := ((nP x+w2) rounded max:0) min:w. |
10665 nX := ((nP x+w2) rounded max:0) min:w. |
10666 nY := ((nP y+h2) rounded max:0) min:h. |
10666 nY := ((nP y+h2) rounded max:0) min:h. |
10667 (nX > w or:[nX < 0]) ifTrue:[ |
10667 (nX > w or:[nX < 0]) ifTrue:[ |
10668 white |
10668 white |
10669 ] ifFalse:[ |
10669 ] ifFalse:[ |
10670 (nY > h or:[nY < 0]) ifTrue:[ |
10670 (nY > h or:[nY < 0]) ifTrue:[ |
10671 white |
10671 white |
10672 ] ifFalse:[ |
10672 ] ifFalse:[ |
10673 oldImage pixelAtX:nX y:nY |
10673 oldImage pixelAtX:nX y:nY |
10674 ] |
10674 ] |
10675 ] |
10675 ] |
10676 ]) inspect. |
10676 ]) inspect. |
10677 " |
10677 " |
10678 "fisheye effect: |
10678 "fisheye effect: |
10679 |
10679 |
10680 |i w h w2 h2 R white| |
10680 |i w h w2 h2 R white| |
10681 |
10681 |
10686 w2 := w // 2. |
10686 w2 := w // 2. |
10687 h2 := h // 2. |
10687 h2 := h // 2. |
10688 R := w2. |
10688 R := w2. |
10689 white := i valueFromColor:Color white. |
10689 white := i valueFromColor:Color white. |
10690 (i withPixelFunctionAppliedToPixels:[:oldImage :oldPixel :x :y | |
10690 (i withPixelFunctionAppliedToPixels:[:oldImage :oldPixel :x :y | |
10691 |p r a nR nP nX nY| |
10691 |p r a nR nP nX nY| |
10692 |
10692 |
10693 p := (x-w2)@(y-h2). |
10693 p := (x-w2)@(y-h2). |
10694 r := p r. |
10694 r := p r. |
10695 a := p theta. |
10695 a := p theta. |
10696 nR := r * r / R. |
10696 nR := r * r / R. |
10697 nP := Point r:nR theta:a. |
10697 nP := Point r:nR theta:a. |
10698 nX := (nP x+w2) rounded. |
10698 nX := (nP x+w2) rounded. |
10699 nY := (nP y+h2) rounded. |
10699 nY := (nP y+h2) rounded. |
10700 (nX > w or:[nX < 0]) ifTrue:[ |
10700 (nX > w or:[nX < 0]) ifTrue:[ |
10701 white |
10701 white |
10702 ] ifFalse:[ |
10702 ] ifFalse:[ |
10703 (nY > h or:[nY < 0]) ifTrue:[ |
10703 (nY > h or:[nY < 0]) ifTrue:[ |
10704 white |
10704 white |
10705 ] ifFalse:[ |
10705 ] ifFalse:[ |
10706 oldImage pixelAtX:nX y:nY |
10706 oldImage pixelAtX:nX y:nY |
10707 ] |
10707 ] |
10708 ] |
10708 ] |
10709 ]) inspect. |
10709 ]) inspect. |
10710 " |
10710 " |
10711 |
10711 |
10712 "Created: 24.4.1997 / 18:37:17 / cg" |
10712 "Created: 24.4.1997 / 18:37:17 / cg" |
10713 "Modified: 24.4.1997 / 18:40:02 / cg" |
10713 "Modified: 24.4.1997 / 18:40:02 / cg" |
10714 ! ! |
10714 ! ! |
10803 applyPixelValuesTo:pixelFunctionBlock into:newImage in:aRectangle |
10803 applyPixelValuesTo:pixelFunctionBlock into:newImage in:aRectangle |
10804 "helper for withPixelFunctionAppliedToValues: |
10804 "helper for withPixelFunctionAppliedToValues: |
10805 enumerate pixelValues and evaluate the block for each. |
10805 enumerate pixelValues and evaluate the block for each. |
10806 To be redefined by subclasses for better performance." |
10806 To be redefined by subclasses for better performance." |
10807 |
10807 |
10808 ^ self applyPixelValuesTo:pixelFunctionBlock in:aRectangle into:newImage |
10808 ^ self applyPixelValuesTo:pixelFunctionBlock in:aRectangle into:newImage |
10809 ! |
10809 ! |
10810 |
10810 |
10811 magnifyBy:scale |
10811 magnifyBy:scale |
10812 "obsolete: has been renamed to magnifiedBy: for ST-80 compatibility |
10812 "obsolete: has been renamed to magnifiedBy: for ST-80 compatibility |
10813 and name consistency ..." |
10813 and name consistency ..." |
10824 colorMap - otherwise, an error will be reported. |
10824 colorMap - otherwise, an error will be reported. |
10825 |
10825 |
10826 WARNING: |
10826 WARNING: |
10827 This implementation is a very slow fallback general algorithm |
10827 This implementation is a very slow fallback general algorithm |
10828 (the loop over the source pixels is very slow). |
10828 (the loop over the source pixels is very slow). |
10829 If this method is used heavily, you may want to redefine it in |
10829 If this method is used heavily, you may want to redefine it in |
10830 concrete subclasses for the common case of of copying from an Image |
10830 concrete subclasses for the common case of of copying from an Image |
10831 with the same depth & palette. |
10831 with the same depth & palette. |
10832 If you do heavy image processing, specialized versions are even req'd |
10832 If you do heavy image processing, specialized versions are even req'd |
10833 for other cases, rewriting the inner loops as inline C-code." |
10833 for other cases, rewriting the inner loops as inline C-code." |
10834 |
10834 |
10835 |dX dY| |
10835 |dX dY| |
10836 |
10836 |
10837 dX := srcX-dstX. |
10837 dX := srcX-dstX. |
10838 dY := srcY-dstY. |
10838 dY := srcY-dstY. |
10839 |
10839 |
10840 ((photometric == anImage photometric) |
10840 ((photometric == anImage photometric) |
10841 and:[self bitsPerPixel == anImage bitsPerPixel |
10841 and:[self bitsPerPixel == anImage bitsPerPixel |
10842 and:[colorMap = anImage colorMap]]) ifTrue:[ |
10842 and:[colorMap = anImage colorMap]]) ifTrue:[ |
10843 "/ can loop over values |
10843 "/ can loop over values |
10844 anImage valuesFromX:srcX y:srcY |
10844 anImage valuesFromX:srcX y:srcY |
10845 toX:srcX+w-1 y:srcY+h-1 |
10845 toX:srcX+w-1 y:srcY+h-1 |
10846 do:[:x :y :pixelValue | |
10846 do:[:x :y :pixelValue | |
10847 self pixelAtX:x-dX y:y-dY put:pixelValue. |
10847 self pixelAtX:x-dX y:y-dY put:pixelValue. |
10848 ] |
10848 ] |
10849 ] ifFalse:[ |
10849 ] ifFalse:[ |
10850 "/ must loop over colors - horribly slow |
10850 "/ must loop over colors - horribly slow |
10851 anImage colorsFromX:srcX y:srcY |
10851 anImage colorsFromX:srcX y:srcY |
10852 toX:srcX+w-1 y:srcY+h-1 |
10852 toX:srcX+w-1 y:srcY+h-1 |
10853 do:[:x :y :clr | |
10853 do:[:x :y :clr | |
10854 self colorAtX:x-dX y:y-dY put:clr. |
10854 self colorAtX:x-dX y:y-dY put:clr. |
10855 ] |
10855 ] |
10856 ]. |
10856 ]. |
10857 |
10857 |
10858 (mask isNil and:[anImage mask notNil]) ifTrue:[ |
10858 (mask isNil and:[anImage mask notNil]) ifTrue:[ |
10859 "/ I have no mask; copied image has |
10859 "/ I have no mask; copied image has |
10860 self createMask. |
10860 self createMask. |
10861 ]. |
10861 ]. |
10862 |
10862 |
10863 mask notNil ifTrue:[ |
10863 mask notNil ifTrue:[ |
10864 anImage mask notNil ifTrue:[ |
10864 anImage mask notNil ifTrue:[ |
10865 "/ both have a mask |
10865 "/ both have a mask |
10866 mask copyFrom:anImage mask x:srcX y:srcY toX:dstX y:dstY width:w height:h |
10866 mask copyFrom:anImage mask x:srcX y:srcY toX:dstX y:dstY width:w height:h |
10867 ] ifFalse:[ |
10867 ] ifFalse:[ |
10868 "/ I have a mask - copied image has not |
10868 "/ I have a mask - copied image has not |
10869 mask fillRectangleX:dstX y:dstY width:w height:h withValue:1 |
10869 mask fillRectangleX:dstX y:dstY width:w height:h withValue:1 |
10870 ] |
10870 ] |
10871 "/ ] ifFalse:[ |
10871 "/ ] ifFalse:[ |
10872 "/ anImage mask notNil ifTrue:[ |
10872 "/ anImage mask notNil ifTrue:[ |
10873 "/ "/ I have no mask; copied image has (already handled) |
10873 "/ "/ I have no mask; copied image has (already handled) |
10874 "/ ] ifFalse:[ |
10874 "/ ] ifFalse:[ |
10875 "/ "/ none has a mask - nothing to do. |
10875 "/ "/ none has a mask - nothing to do. |
10921 aStream nextPutAll:'(' , self class name , ' new)'. |
10921 aStream nextPutAll:'(' , self class name , ' new)'. |
10922 aStream nextPutAll:' width: '. width storeOn:aStream. |
10922 aStream nextPutAll:' width: '. width storeOn:aStream. |
10923 aStream nextPutAll:'; height: '. height storeOn:aStream. |
10923 aStream nextPutAll:'; height: '. height storeOn:aStream. |
10924 aStream nextPutAll:'; photometric:('. photometric storeOn:aStream. |
10924 aStream nextPutAll:'; photometric:('. photometric storeOn:aStream. |
10925 aStream nextPutAll:'); bitsPerSample:('. bitsPerSample storeOn:aStream. |
10925 aStream nextPutAll:'); bitsPerSample:('. bitsPerSample storeOn:aStream. |
10926 aStream nextPutAll:'); samplesPerPixel:('. samplesPerPixel storeOn:aStream. |
10926 aStream nextPutAll:'); samplesPerPixel:('. samplesPerPixel storeOn:aStream. |
10927 aStream nextPutAll:'); bits:(ByteArray fromPackedString:'. self bits asPackedString storeOn:aStream. aStream nextPutAll:') '. |
10927 aStream nextPutAll:'); bits:(ByteArray fromPackedString:'. self bits asPackedString storeOn:aStream. aStream nextPutAll:') '. |
10928 |
10928 |
10929 colorMap notNil ifTrue:[ |
10929 colorMap notNil ifTrue:[ |
10930 self depth <= 8 ifTrue:[ |
10930 self depth <= 8 ifTrue:[ |
10931 "/ cut off unused colors ... |
10931 "/ cut off unused colors ... |
10932 usedValues := self usedValues. |
10932 usedValues := self usedValues. |
10933 colors := colorMap copyFrom:1 to:((usedValues max+1) min:colorMap size). |
10933 colors := colorMap copyFrom:1 to:((usedValues max+1) min:colorMap size). |
10934 |
10934 |
10935 colorMapArray := OrderedCollection new. |
10935 colorMapArray := OrderedCollection new. |
10936 colors do:[:clr| colorMapArray add:(clr redByte); add:(clr greenByte); add:(clr blueByte)]. |
10936 colors do:[:clr| colorMapArray add:(clr redByte); add:(clr greenByte); add:(clr blueByte)]. |
10937 aStream nextPutAll:'; colorMapFromArray:'. |
10937 aStream nextPutAll:'; colorMapFromArray:'. |
10938 colorMapArray asByteArray storeOn:aStream. |
10938 colorMapArray asByteArray storeOn:aStream. |
10939 ] ifFalse:[ |
10939 ] ifFalse:[ |
10940 aStream nextPutAll:'; colorMap:('. |
10940 aStream nextPutAll:'; colorMap:('. |
10941 colorMap storeOn:aStream. |
10941 colorMap storeOn:aStream. |
10942 aStream nextPutAll:')' |
10942 aStream nextPutAll:')' |
10943 ] |
10943 ] |
10944 ]. |
10944 ]. |
10945 mask notNil ifTrue:[ |
10945 mask notNil ifTrue:[ |
10946 aStream nextPutAll:'; mask:('. |
10946 aStream nextPutAll:'; mask:('. |
10947 mask storeOn:aStream. |
10947 mask storeOn:aStream. |
10948 aStream nextPutAll:')'. |
10948 aStream nextPutAll:')'. |
10949 ]. |
10949 ]. |
10950 aStream nextPutAll:'; yourself' |
10950 aStream nextPutAll:'; yourself' |
10951 |
10951 |
10952 "Modified: / 22.8.1998 / 12:55:21 / cg" |
10952 "Modified: / 22.8.1998 / 12:55:21 / cg" |
10953 ! ! |
10953 ! ! |
10960 on it. The best format is the one with the same number or more bits per |
10960 on it. The best format is the one with the same number or more bits per |
10961 pixel. Here, the smallest format found which can represent enough pixels is taken." |
10961 pixel. Here, the smallest format found which can represent enough pixels is taken." |
10962 |
10962 |
10963 |bestDeviceDepth |
10963 |bestDeviceDepth |
10964 bestDeviceBitsPerPixel "{ Class: SmallInteger }" |
10964 bestDeviceBitsPerPixel "{ Class: SmallInteger }" |
10965 "maxDepth" |
10965 "maxDepth" |
10966 bestInfo maxInfo |
10966 bestInfo maxInfo |
10967 myDepth "{ Class: SmallInteger }" |
10967 myDepth "{ Class: SmallInteger }" |
10968 maxBitsPerPixel "{ Class: SmallInteger }"| |
10968 maxBitsPerPixel "{ Class: SmallInteger }"| |
10969 |
10969 |
10970 myDepth := self bitsPerPixel. |
10970 myDepth := self bitsPerPixel. |
10971 maxBitsPerPixel := 0. |
10971 maxBitsPerPixel := 0. |
10979 |
10979 |
10980 "/ for now, ignore all depth's which are neither 1 nor the |
10980 "/ for now, ignore all depth's which are neither 1 nor the |
10981 "/ devices depth. |
10981 "/ devices depth. |
10982 "/ (actually, many devices can handle other pixMap formats, |
10982 "/ (actually, many devices can handle other pixMap formats, |
10983 "/ but I dont know (yet) how to pass the correct color info |
10983 "/ but I dont know (yet) how to pass the correct color info |
10984 |
10984 |
10985 ((deviceImageDepth == 1) or:[deviceImageDepth == aDevice depth]) ifTrue:[ |
10985 ((deviceImageDepth == 1) or:[deviceImageDepth == aDevice depth]) ifTrue:[ |
10986 |
10986 |
10987 deviceImageBitsPerPixel > maxBitsPerPixel ifTrue:[ |
10987 deviceImageBitsPerPixel > maxBitsPerPixel ifTrue:[ |
10988 maxInfo := entry. |
10988 maxInfo := entry. |
10989 "/ maxBitsPerPixel := deviceImageBitsPerPixel. |
10989 "/ maxBitsPerPixel := deviceImageBitsPerPixel. |
11006 or:[deviceImageBitsPerPixel < bestDeviceBitsPerPixel]) ifTrue:[ |
11006 or:[deviceImageBitsPerPixel < bestDeviceBitsPerPixel]) ifTrue:[ |
11007 bestInfo := entry. |
11007 bestInfo := entry. |
11008 bestDeviceDepth := deviceImageDepth. |
11008 bestDeviceDepth := deviceImageDepth. |
11009 bestDeviceBitsPerPixel := deviceImageBitsPerPixel. |
11009 bestDeviceBitsPerPixel := deviceImageBitsPerPixel. |
11010 ] |
11010 ] |
11011 ] |
11011 ] |
11012 ]. |
11012 ]. |
11013 ]. |
11013 ]. |
11014 ]. |
11014 ]. |
11015 |
11015 |
11016 bestDeviceDepth isNil ifTrue:[ |
11016 bestDeviceDepth isNil ifTrue:[ |
11062 ]. |
11062 ]. |
11063 photometric == #palette ifTrue:[ |
11063 photometric == #palette ifTrue:[ |
11064 self setColorMap:(anImage colorMap copy). |
11064 self setColorMap:(anImage colorMap copy). |
11065 " |
11065 " |
11066 must generate/compress the colormap, if source image has higher depth |
11066 must generate/compress the colormap, if source image has higher depth |
11067 than myself. |
11067 than myself. |
11068 " |
11068 " |
11069 (colorMap isNil |
11069 (colorMap isNil |
11070 or:[anImage bitsPerPixel > self bitsPerPixel]) ifTrue:[ |
11070 or:[anImage bitsPerPixel > self bitsPerPixel]) ifTrue:[ |
11071 " |
11071 " |
11072 get used colors are extracted into our colorMap |
11072 get used colors are extracted into our colorMap |
11093 "Modified: 10.1.1997 / 17:52:21 / cg" |
11093 "Modified: 10.1.1997 / 17:52:21 / cg" |
11094 ! |
11094 ! |
11095 |
11095 |
11096 greyByteMapForRange:range |
11096 greyByteMapForRange:range |
11097 "return a collection to map from pixelValues to greyLevels |
11097 "return a collection to map from pixelValues to greyLevels |
11098 in the range 0..range. |
11098 in the range 0..range. |
11099 Range must be < 256 (for elements to fit into a ByteArray). |
11099 Range must be < 256 (for elements to fit into a ByteArray). |
11100 The values are rounded towards the nearest pixel." |
11100 The values are rounded towards the nearest pixel." |
11101 |
11101 |
11102 |d clr val greyMap r |
11102 |d clr val greyMap r |
11103 n "{ Class: SmallInteger }"| |
11103 n "{ Class: SmallInteger }"| |
11232 " |
11232 " |
11233 |
11233 |
11234 "Modified: 1.3.1997 / 15:48:49 / cg" |
11234 "Modified: 1.3.1997 / 15:48:49 / cg" |
11235 ! |
11235 ! |
11236 |
11236 |
11237 magnifyRowFrom:srcBytes offset:srcStart |
11237 magnifyRowFrom:srcBytes offset:srcStart |
11238 into:dstBytes offset:dstStart factor:mX |
11238 into:dstBytes offset:dstStart factor:mX |
11239 |
11239 |
11240 "magnify a single pixel row - can only magnify by integer factors, |
11240 "magnify a single pixel row - can only magnify by integer factors, |
11241 can only magnify 1,2,4,8 and 24 bit-per-pixel images. But this is done fast." |
11241 can only magnify 1,2,4,8 and 24 bit-per-pixel images. But this is done fast." |
11242 |
11242 |
11243 ^ self subclassResponsibility |
11243 ^ self subclassResponsibility |
11244 ! |
11244 ! |
11245 |
11245 |
11246 makeDeviceGrayPixmapOn:aDevice depth:depth fromArray:bits |
11246 makeDeviceGrayPixmapOn:aDevice depth:depth fromArray:bits |
11247 "given the bits of a grey/color bitmap, 8-bit padded and |
11247 "given the bits of a grey/color bitmap, 8-bit padded and |
11248 pixels interpreted as greyValues, 0 is black, |
11248 pixels interpreted as greyValues, 0 is black, |
11249 create a device form for it" |
11249 create a device form for it" |
11250 |
11250 |
11251 |f| |
11251 |f| |
11252 |
11252 |
11253 f := Form width:width height:height depth:depth on:aDevice. |
11253 f := Form width:width height:height depth:depth on:aDevice. |
11258 |
11258 |
11259 (aDevice blackpixel ~~ 0) ifTrue:[ |
11259 (aDevice blackpixel ~~ 0) ifTrue:[ |
11260 "/ have to invert bits |
11260 "/ have to invert bits |
11261 f function:#copyInverted |
11261 f function:#copyInverted |
11262 ]. |
11262 ]. |
11263 aDevice |
11263 aDevice |
11264 drawBits:bits |
11264 drawBits:bits |
11265 depth:depth |
11265 depth:depth |
11266 padding:8 |
11266 padding:8 |
11267 width:width height:height |
11267 width:width height:height |
11268 x:0 y:0 |
11268 x:0 y:0 |
11269 into:(f id) |
11269 into:(f id) |
11270 x:0 y:0 |
11270 x:0 y:0 |
11271 width:width height:height |
11271 width:width height:height |
11272 with:(f gcId). |
11272 with:(f gcId). |
11273 ^ f |
11273 ^ f |
11274 |
11274 |
11275 "Created: 10.6.1996 / 20:10:31 / cg" |
11275 "Created: 10.6.1996 / 20:10:31 / cg" |
11276 ! |
11276 ! |
11287 "Modified: 17.4.1997 / 01:07:38 / cg" |
11287 "Modified: 17.4.1997 / 01:07:38 / cg" |
11288 ! |
11288 ! |
11289 |
11289 |
11290 makeDevicePixmapOn:aDevice depth:depth fromArray:bits |
11290 makeDevicePixmapOn:aDevice depth:depth fromArray:bits |
11291 "given the bits of a grey/color bitmap, 8-bit padded and |
11291 "given the bits of a grey/color bitmap, 8-bit padded and |
11292 pixels interpreted as in the devices colormap, |
11292 pixels interpreted as in the devices colormap, |
11293 create a device form for it" |
11293 create a device form for it" |
11294 |
11294 |
11295 |f| |
11295 |f| |
11296 |
11296 |
11297 f := Form width:width height:height depth:depth on:aDevice. |
11297 f := Form width:width height:height depth:depth on:aDevice. |
11298 f isNil ifTrue:[^ nil]. |
11298 f isNil ifTrue:[^ nil]. |
11299 |
11299 |
11300 f bits:bits. |
11300 f bits:bits. |
11301 f initGC. |
11301 f initGC. |
11302 |
11302 |
11303 aDevice |
11303 aDevice |
11304 drawBits:bits |
11304 drawBits:bits |
11305 depth:depth |
11305 depth:depth |
11306 padding:8 |
11306 padding:8 |
11307 width:width height:height |
11307 width:width height:height |
11308 x:0 y:0 |
11308 x:0 y:0 |
11309 into:(f id) |
11309 into:(f id) |
11310 x:0 y:0 |
11310 x:0 y:0 |
11311 width:width height:height |
11311 width:width height:height |
11312 with:(f gcId). |
11312 with:(f gcId). |
11313 ^ f |
11313 ^ f |
11314 |
11314 |
11315 "Created: 10.6.1996 / 17:56:08 / cg" |
11315 "Created: 10.6.1996 / 17:56:08 / cg" |
11316 "Modified: 10.6.1996 / 20:11:27 / cg" |
11316 "Modified: 10.6.1996 / 20:11:27 / cg" |
11380 |
11380 |
11381 averageColor |
11381 averageColor |
11382 "return the average color of the image. |
11382 "return the average color of the image. |
11383 This usually only makes sense for textures and patterns |
11383 This usually only makes sense for textures and patterns |
11384 (i.e. to compute shadow & light colors for viewBackgrounds). |
11384 (i.e. to compute shadow & light colors for viewBackgrounds). |
11385 Notice, that for the above purpose, it is usually ok to process |
11385 Notice, that for the above purpose, it is usually ok to process |
11386 a subImage - i.e. use Image>>averageColorIn: on a smaller rectangle" |
11386 a subImage - i.e. use Image>>averageColorIn: on a smaller rectangle" |
11387 |
11387 |
11388 ^ self averageColorIn:(0@0 corner:(width-1)@(height-1)) |
11388 ^ self averageColorIn:(0@0 corner:(width-1)@(height-1)) |
11389 ! |
11389 ! |
11390 |
11390 |
11391 averageColorIn:aRectangle |
11391 averageColorIn:aRectangle |
11392 "return the images average color in an area. |
11392 "return the images average color in an area. |
11393 The implementation below is slow - so you may want to |
11393 The implementation below is slow - so you may want to |
11394 create tuned versions for DepthXImage if you plan to do |
11394 create tuned versions for DepthXImage if you plan to do |
11395 heavy image processing ... |
11395 heavy image processing ... |
11396 (also, creating tuned versions of the enumeration messages helps a lot)" |
11396 (also, creating tuned versions of the enumeration messages helps a lot)" |
11397 |
11397 |
11398 |x0 "{ Class:SmallInteger }" |
11398 |x0 "{ Class:SmallInteger }" |
11399 y0 "{ Class:SmallInteger }" |
11399 y0 "{ Class:SmallInteger }" |
11400 x1 "{ Class:SmallInteger }" |
11400 x1 "{ Class:SmallInteger }" |
11401 y1 "{ Class:SmallInteger }" |
11401 y1 "{ Class:SmallInteger }" |
11402 sumRed sumGreen sumBlue n| |
11402 sumRed sumGreen sumBlue n| |
11403 |
11403 |
11404 sumRed := sumGreen := sumBlue := 0. |
11404 sumRed := sumGreen := sumBlue := 0. |
11405 y0 := aRectangle top. |
11405 y0 := aRectangle top. |
11406 y1 := aRectangle bottom. |
11406 y1 := aRectangle bottom. |
11407 x0 := aRectangle left. |
11407 x0 := aRectangle left. |
11408 x1 := aRectangle right. |
11408 x1 := aRectangle right. |
11409 |
11409 |
11410 n := (x1 - x0 + 1) * (y1 - y0 + 1). |
11410 n := (x1 - x0 + 1) * (y1 - y0 + 1). |
11411 mask isNil ifTrue:[ |
11411 mask isNil ifTrue:[ |
11412 self colorsFromX:x0 y:y0 toX:x1 y:y1 do:[:x :y :colorAtXY | |
11412 self colorsFromX:x0 y:y0 toX:x1 y:y1 do:[:x :y :colorAtXY | |
11413 sumRed := sumRed + colorAtXY red. |
11413 sumRed := sumRed + colorAtXY red. |
11414 sumGreen := sumGreen + colorAtXY green. |
11414 sumGreen := sumGreen + colorAtXY green. |
11415 sumBlue := sumBlue + colorAtXY blue. |
11415 sumBlue := sumBlue + colorAtXY blue. |
11585 |
11585 |
11586 |p maxPixel clr r g b c m y k| |
11586 |p maxPixel clr r g b c m y k| |
11587 |
11587 |
11588 p := photometric. |
11588 p := photometric. |
11589 p isNil ifTrue:[ |
11589 p isNil ifTrue:[ |
11590 colorMap notNil ifTrue:[ |
11590 colorMap notNil ifTrue:[ |
11591 p := #palette |
11591 p := #palette |
11592 ] ifFalse:[ |
11592 ] ifFalse:[ |
11593 "/ 'Image [warning]: no photometric - assume greyscale' infoPrintCR |
11593 "/ 'Image [warning]: no photometric - assume greyscale' infoPrintCR |
11594 p := #blackIs0 |
11594 p := #blackIs0 |
11595 ] |
11595 ] |
11596 ]. |
11596 ]. |
11597 |
11597 |
11598 p == #blackIs0 ifTrue:[ |
11598 p == #blackIs0 ifTrue:[ |
11599 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
11599 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
11600 ^ Color gray:(pixelValue * (100 / maxPixel)). |
11600 ^ Color gray:(pixelValue * (100 / maxPixel)). |
11601 ]. |
11601 ]. |
11602 |
11602 |
11603 p == #whiteIs0 ifTrue:[ |
11603 p == #whiteIs0 ifTrue:[ |
11604 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
11604 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
11605 ^ Color gray:100 - (pixelValue * (100 / maxPixel)). |
11605 ^ Color gray:100 - (pixelValue * (100 / maxPixel)). |
11606 ]. |
11606 ]. |
11607 |
11607 |
11608 p == #palette ifTrue:[ |
11608 p == #palette ifTrue:[ |
11609 pixelValue >= colorMap size ifTrue:[ |
11609 pixelValue >= colorMap size ifTrue:[ |
11610 ^ Color black |
11610 ^ Color black |
11611 ]. |
11611 ]. |
11612 clr := colorMap at:(pixelValue + 1). |
11612 clr := colorMap at:(pixelValue + 1). |
11613 clr isNil ifTrue:[ |
11613 clr isNil ifTrue:[ |
11614 ^ Color black. |
11614 ^ Color black. |
11615 ]. |
11615 ]. |
11616 ^ clr. |
11616 ^ clr. |
11617 ]. |
11617 ]. |
11618 |
11618 |
11619 p == #rgb ifTrue:[ |
11619 p == #rgb ifTrue:[ |
11620 r := self redBitsOf:pixelValue. |
11620 r := self redBitsOf:pixelValue. |
11621 g := self greenBitsOf:pixelValue. |
11621 g := self greenBitsOf:pixelValue. |
11622 b := self blueBitsOf:pixelValue. |
11622 b := self blueBitsOf:pixelValue. |
11623 "/ must scale to byte value... |
11623 "/ must scale to byte value... |
11624 r := r bitShift:(8 - (bitsPerSample at:1)). |
11624 r := r bitShift:(8 - (bitsPerSample at:1)). |
11625 g := g bitShift:(8 - (bitsPerSample at:2)). |
11625 g := g bitShift:(8 - (bitsPerSample at:2)). |
11626 b := b bitShift:(8 - (bitsPerSample at:3)). |
11626 b := b bitShift:(8 - (bitsPerSample at:3)). |
11627 ^ Color redByte:r greenByte:g blueByte:b |
11627 ^ Color redByte:r greenByte:g blueByte:b |
11628 ]. |
11628 ]. |
11629 |
11629 |
11630 p == #cmyk ifTrue:[ |
11630 p == #cmyk ifTrue:[ |
11631 c := self cyanComponentOfCMYK:pixelValue. |
11631 c := self cyanComponentOfCMYK:pixelValue. |
11632 m := self magentaComponentOfCMYK:pixelValue. |
11632 m := self magentaComponentOfCMYK:pixelValue. |
11633 y := self yellowComponentOfCMYK:pixelValue. |
11633 y := self yellowComponentOfCMYK:pixelValue. |
11634 k := self blackComponentOfCMYK:pixelValue. |
11634 k := self blackComponentOfCMYK:pixelValue. |
11635 ^ Color cyan:c magenta:m yellow:y black:k. |
11635 ^ Color cyan:c magenta:m yellow:y black:k. |
11636 ]. |
11636 ]. |
11637 |
11637 |
11638 p == #cmy ifTrue:[ |
11638 p == #cmy ifTrue:[ |
11639 c := self cyanComponentOfCMY:pixelValue. |
11639 c := self cyanComponentOfCMY:pixelValue. |
11640 m := self magentaComponentOfCMY:pixelValue. |
11640 m := self magentaComponentOfCMY:pixelValue. |
11641 y := self yellowComponentOfCMY:pixelValue. |
11641 y := self yellowComponentOfCMY:pixelValue. |
11642 ^ Color cyan:c magenta:m yellow:y. |
11642 ^ Color cyan:c magenta:m yellow:y. |
11643 ]. |
11643 ]. |
11644 |
11644 |
11645 self error:'invalid (unsupported) photometric' |
11645 self error:'invalid (unsupported) photometric' |
11646 |
11646 |
11647 "Created: 8.6.1996 / 08:46:18 / cg" |
11647 "Created: 8.6.1996 / 08:46:18 / cg" |
11746 "return the shift amount used with translation from pixelValues to greenBits" |
11746 "return the shift amount used with translation from pixelValues to greenBits" |
11747 |
11747 |
11748 |greenBits| |
11748 |greenBits| |
11749 |
11749 |
11750 samplesPerPixel >= 3 ifTrue:[ |
11750 samplesPerPixel >= 3 ifTrue:[ |
11751 greenBits := bitsPerSample at:3. |
11751 greenBits := bitsPerSample at:3. |
11752 ^ greenBits negated |
11752 ^ greenBits negated |
11753 ]. |
11753 ]. |
11754 |
11754 |
11755 self subclassResponsibility |
11755 self subclassResponsibility |
11756 ! |
11756 ! |
11757 |
11757 |
11844 "Modified: 24.4.1997 / 15:34:34 / cg" |
11844 "Modified: 24.4.1997 / 15:34:34 / cg" |
11845 ! |
11845 ! |
11846 |
11846 |
11847 realColorMap |
11847 realColorMap |
11848 "return a collection usable as a real colormap of the image. |
11848 "return a collection usable as a real colormap of the image. |
11849 For palette images, this is the internal colormap; |
11849 For palette images, this is the internal colormap; |
11850 for other photometrics (which do not have a real colormap), synthesize one. |
11850 for other photometrics (which do not have a real colormap), synthesize one. |
11851 This is different from #colorMap, which returns nil for non palette images." |
11851 This is different from #colorMap, which returns nil for non palette images." |
11852 |
11852 |
11853 |d nEntries "{ Class: SmallInteger }" |
11853 |d nEntries "{ Class: SmallInteger }" |
11854 colorArray| |
11854 colorArray| |
11898 |
11898 |
11899 |set last| |
11899 |set last| |
11900 |
11900 |
11901 set := IdentitySet new. |
11901 set := IdentitySet new. |
11902 self valuesFromX:0 y:0 toX:(self width-1) y:(self height-1) do:[:x :y :pixel | |
11902 self valuesFromX:0 y:0 toX:(self width-1) y:(self height-1) do:[:x :y :pixel | |
11903 pixel ~~ last ifTrue:[ |
11903 pixel ~~ last ifTrue:[ |
11904 set add:pixel. |
11904 set add:pixel. |
11905 last := pixel. |
11905 last := pixel. |
11906 ] |
11906 ] |
11907 ]. |
11907 ]. |
11908 ^ set |
11908 ^ set |
11909 |
11909 |
11910 " |
11910 " |
11911 (Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') usedValues |
11911 (Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') usedValues |
11958 greenBits := bitsPerSample at:2. |
11958 greenBits := bitsPerSample at:2. |
11959 blueBits := bitsPerSample at:3. |
11959 blueBits := bitsPerSample at:3. |
11960 |
11960 |
11961 s := (1 bitShift:redBits) - 1. |
11961 s := (1 bitShift:redBits) - 1. |
11962 |
11962 |
11963 ^ 100.0 / s * |
11963 ^ 100.0 / s * |
11964 ((pixel bitShift:(greenBits + blueBits) negated) |
11964 ((pixel bitShift:(greenBits + blueBits) negated) |
11965 bitAnd:(1 bitShift:redBits)-1) |
11965 bitAnd:(1 bitShift:redBits)-1) |
11966 ]. |
11966 ]. |
11967 |
11967 |
11968 self subclassResponsibility |
11968 self subclassResponsibility |
12010 |
12010 |
12011 |p maxPixel clr r g b c m y k| |
12011 |p maxPixel clr r g b c m y k| |
12012 |
12012 |
12013 p := photometric. |
12013 p := photometric. |
12014 p isNil ifTrue:[ |
12014 p isNil ifTrue:[ |
12015 colorMap notNil ifTrue:[ |
12015 colorMap notNil ifTrue:[ |
12016 p := #palette |
12016 p := #palette |
12017 ] ifFalse:[ |
12017 ] ifFalse:[ |
12018 "/ 'Image [warning]: no photometric - assume greyscale' infoPrintCR |
12018 "/ 'Image [warning]: no photometric - assume greyscale' infoPrintCR |
12019 p := #blackIs0 |
12019 p := #blackIs0 |
12020 ] |
12020 ] |
12021 ]. |
12021 ]. |
12022 |
12022 |
12023 p == #blackIs0 ifTrue:[ |
12023 p == #blackIs0 ifTrue:[ |
12024 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
12024 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
12025 b := pixelValue * 255 // maxPixel. |
12025 b := pixelValue * 255 // maxPixel. |
12026 ^ (((b bitShift:8) bitOr:b) bitShift:8) bitOr:b |
12026 ^ (((b bitShift:8) bitOr:b) bitShift:8) bitOr:b |
12027 ]. |
12027 ]. |
12028 |
12028 |
12029 p == #whiteIs0 ifTrue:[ |
12029 p == #whiteIs0 ifTrue:[ |
12030 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
12030 maxPixel := (1 bitShift:self bitsPerPixel) - 1. |
12031 b := 255 - (pixelValue * 255 // maxPixel). |
12031 b := 255 - (pixelValue * 255 // maxPixel). |
12032 ^ (((b bitShift:8) bitOr:b) bitShift:8) bitOr:b |
12032 ^ (((b bitShift:8) bitOr:b) bitShift:8) bitOr:b |
12033 ]. |
12033 ]. |
12034 |
12034 |
12035 p == #palette ifTrue:[ |
12035 p == #palette ifTrue:[ |
12036 pixelValue >= colorMap size ifTrue:[ |
12036 pixelValue >= colorMap size ifTrue:[ |
12037 ^ 0 "/ black |
12037 ^ 0 "/ black |
12038 ]. |
12038 ]. |
12039 clr := colorMap at:(pixelValue + 1). |
12039 clr := colorMap at:(pixelValue + 1). |
12040 clr isNil ifTrue:[ |
12040 clr isNil ifTrue:[ |
12041 ^ 0 "/ black |
12041 ^ 0 "/ black |
12042 ]. |
12042 ]. |
12043 ^ clr rgbValue. |
12043 ^ clr rgbValue. |
12044 ]. |
12044 ]. |
12045 |
12045 |
12046 p == #rgb ifTrue:[ |
12046 p == #rgb ifTrue:[ |
12047 r := self redBitsOf:pixelValue. |
12047 r := self redBitsOf:pixelValue. |
12048 g := self greenBitsOf:pixelValue. |
12048 g := self greenBitsOf:pixelValue. |
12049 b := self blueBitsOf:pixelValue. |
12049 b := self blueBitsOf:pixelValue. |
12050 "/ must scale to byte value... |
12050 "/ must scale to byte value... |
12051 r := r bitShift:(8 - (bitsPerSample at:1)). |
12051 r := r bitShift:(8 - (bitsPerSample at:1)). |
12052 g := g bitShift:(8 - (bitsPerSample at:2)). |
12052 g := g bitShift:(8 - (bitsPerSample at:2)). |
12053 b := b bitShift:(8 - (bitsPerSample at:3)). |
12053 b := b bitShift:(8 - (bitsPerSample at:3)). |
12054 ^ (((r bitShift:8) bitOr:g) bitShift:8) bitOr:b |
12054 ^ (((r bitShift:8) bitOr:g) bitShift:8) bitOr:b |
12055 ]. |
12055 ]. |
12056 |
12056 |
12057 p == #cmyk ifTrue:[ |
12057 p == #cmyk ifTrue:[ |
12058 c := self cyanComponentOfCMYK:pixelValue. |
12058 c := self cyanComponentOfCMYK:pixelValue. |
12059 m := self magentaComponentOfCMYK:pixelValue. |
12059 m := self magentaComponentOfCMYK:pixelValue. |
12060 y := self yellowComponentOfCMYK:pixelValue. |
12060 y := self yellowComponentOfCMYK:pixelValue. |
12061 k := self blackComponentOfCMYK:pixelValue. |
12061 k := self blackComponentOfCMYK:pixelValue. |
12062 ^ (Color cyan:c magenta:m yellow:y black:k) rgbValue. |
12062 ^ (Color cyan:c magenta:m yellow:y black:k) rgbValue. |
12063 ]. |
12063 ]. |
12064 |
12064 |
12065 p == #cmy ifTrue:[ |
12065 p == #cmy ifTrue:[ |
12066 c := self cyanComponentOfCMY:pixelValue. |
12066 c := self cyanComponentOfCMY:pixelValue. |
12067 m := self magentaComponentOfCMY:pixelValue. |
12067 m := self magentaComponentOfCMY:pixelValue. |
12068 y := self yellowComponentOfCMY:pixelValue. |
12068 y := self yellowComponentOfCMY:pixelValue. |
12069 ^ (Color cyan:c magenta:m yellow:y) rgbValue. |
12069 ^ (Color cyan:c magenta:m yellow:y) rgbValue. |
12070 ]. |
12070 ]. |
12071 |
12071 |
12072 self error:'invalid (unsupported) photometric' |
12072 self error:'invalid (unsupported) photometric' |
12073 ! |
12073 ! |
12074 |
12074 |
12079 |
12079 |
12080 |colors| |
12080 |colors| |
12081 |
12081 |
12082 colors := self usedColorsMax:4096. |
12082 colors := self usedColorsMax:4096. |
12083 colors isNil ifTrue:[ |
12083 colors isNil ifTrue:[ |
12084 self error:'too many colors in image'. |
12084 self error:'too many colors in image'. |
12085 ]. |
12085 ]. |
12086 ^ colors |
12086 ^ colors |
12087 |
12087 |
12088 " |
12088 " |
12089 (Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') usedColors |
12089 (Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') usedColors |
12101 (useful when searching rgb images)." |
12101 (useful when searching rgb images)." |
12102 |
12102 |
12103 |usedValues max colors| |
12103 |usedValues max colors| |
12104 |
12104 |
12105 photometric == #rgb ifTrue:[ |
12105 photometric == #rgb ifTrue:[ |
12106 usedValues := IdentitySet new. |
12106 usedValues := IdentitySet new. |
12107 self valuesFromX:0 y:0 toX:(width-1) y:(height-1) |
12107 self valuesFromX:0 y:0 toX:(width-1) y:(height-1) |
12108 do:[:x :y :pixel | |
12108 do:[:x :y :pixel | |
12109 usedValues add:pixel. |
12109 usedValues add:pixel. |
12110 usedValues size > nMax ifTrue:[ |
12110 usedValues size > nMax ifTrue:[ |
12111 "/ too many to be returned here (think of the mass of |
12111 "/ too many to be returned here (think of the mass of |
12112 "/ data to be returned by a 24bit image ... ;-) |
12112 "/ data to be returned by a 24bit image ... ;-) |
12113 ^ nil |
12113 ^ nil |
12114 ] |
12114 ] |
12115 ]. |
12115 ]. |
12116 "/ code below is slightly faster ... |
12116 "/ code below is slightly faster ... |
12117 "/ colors := usedValues collect:[:pixel | self colorFromValue:pixel]. |
12117 "/ colors := usedValues collect:[:pixel | self colorFromValue:pixel]. |
12118 colors := usedValues collect:[:pixel | |r g b| |
12118 colors := usedValues collect:[:pixel | |r g b| |
12119 r := self redBitsOf:pixel. |
12119 r := self redBitsOf:pixel. |
12120 g := self greenBitsOf:pixel. |
12120 g := self greenBitsOf:pixel. |
12121 b := self blueBitsOf:pixel. |
12121 b := self blueBitsOf:pixel. |
12122 "/ must scale to byte value... |
12122 "/ must scale to byte value... |
12123 r := r bitShift:(8 - (bitsPerSample at:1)). |
12123 r := r bitShift:(8 - (bitsPerSample at:1)). |
12124 g := g bitShift:(8 - (bitsPerSample at:2)). |
12124 g := g bitShift:(8 - (bitsPerSample at:2)). |
12125 b := b bitShift:(8 - (bitsPerSample at:3)). |
12125 b := b bitShift:(8 - (bitsPerSample at:3)). |
12126 Color redByte:r greenByte:g blueByte:b |
12126 Color redByte:r greenByte:g blueByte:b |
12127 ]. |
12127 ]. |
12128 ^ colors. |
12128 ^ colors. |
12129 ]. |
12129 ]. |
12130 |
12130 |
12131 usedValues := self usedValues asArray. |
12131 usedValues := self usedValues asArray. |
12132 photometric == #palette ifTrue:[ |
12132 photometric == #palette ifTrue:[ |
12133 colors := usedValues collect:[:val | (colorMap at:val+1 ifAbsent:[Color black])]. |
12133 colors := usedValues collect:[:val | (colorMap at:val+1 ifAbsent:[Color black])]. |
12134 ] ifFalse:[ |
12134 ] ifFalse:[ |
12135 "/ (photometric == #blackIs0 or:[photometric == #whiteIs0]) |
12135 "/ (photometric == #blackIs0 or:[photometric == #whiteIs0]) |
12136 |
12136 |
12137 max := (1 bitShift:self depth) - 1. |
12137 max := (1 bitShift:self depth) - 1. |
12138 colors := usedValues collect:[:val | (Color gray:(100 * val / max ))]. |
12138 colors := usedValues collect:[:val | (Color gray:(100 * val / max ))]. |
12139 ]. |
12139 ]. |
12140 ^ colors asSet |
12140 ^ colors asSet |
12141 |
12141 |
12142 " |
12142 " |
12143 (Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') usedColors |
12143 (Image fromFile:'goodies/bitmaps/gifImages/garfield.gif') usedColors |
12195 photometric == #rgb ifTrue:[ |
12195 photometric == #rgb ifTrue:[ |
12196 samplesPerPixel >= 3 ifTrue:[ |
12196 samplesPerPixel >= 3 ifTrue:[ |
12197 redBits := bitsPerSample at:1. |
12197 redBits := bitsPerSample at:1. |
12198 greenBits := bitsPerSample at:2. |
12198 greenBits := bitsPerSample at:2. |
12199 blueBits := bitsPerSample at:3. |
12199 blueBits := bitsPerSample at:3. |
12200 |
12200 |
12201 "/ map r/g/b to 0..255 |
12201 "/ map r/g/b to 0..255 |
12202 r := (color red / 100.0 * ((1 bitShift:redBits)-1)) rounded. |
12202 r := (color red / 100.0 * ((1 bitShift:redBits)-1)) rounded. |
12203 g := (color green / 100.0 * ((1 bitShift:greenBits)-1)) rounded. |
12203 g := (color green / 100.0 * ((1 bitShift:greenBits)-1)) rounded. |
12204 b := (color blue / 100.0 * ((1 bitShift:blueBits)-1)) rounded. |
12204 b := (color blue / 100.0 * ((1 bitShift:blueBits)-1)) rounded. |
12205 pixel := (((r bitShift:greenBits) + g) bitShift:blueBits) + b. |
12205 pixel := (((r bitShift:greenBits) + g) bitShift:blueBits) + b. |
12222 |
12222 |
12223 photometric == #rgb ifTrue:[ |
12223 photometric == #rgb ifTrue:[ |
12224 samplesPerPixel >= 3 ifTrue:[ |
12224 samplesPerPixel >= 3 ifTrue:[ |
12225 numGreenBits := bitsPerSample at:2. |
12225 numGreenBits := bitsPerSample at:2. |
12226 numBlueBits := bitsPerSample at:3. |
12226 numBlueBits := bitsPerSample at:3. |
12227 |
12227 |
12228 pixel := (((redBits bitShift:numGreenBits) + greenBits) bitShift:numBlueBits) + blueBits. |
12228 pixel := (((redBits bitShift:numGreenBits) + greenBits) bitShift:numBlueBits) + blueBits. |
12229 ^ pixel |
12229 ^ pixel |
12230 ] |
12230 ] |
12231 ]. |
12231 ]. |
12232 |
12232 |
12281 ! ! |
12281 ! ! |
12282 |
12282 |
12283 !Image methodsFor:'saving on file'! |
12283 !Image methodsFor:'saving on file'! |
12284 |
12284 |
12285 saveOn:aFileName |
12285 saveOn:aFileName |
12286 "save the image in aFileName. The suffix of the filename controls the format. |
12286 "save the image in aFileName. The suffix of the filename controls the format. |
12287 Currently, not all formats may be supported |
12287 Currently, not all formats may be supported |
12288 (see ImageReader subclasses implementing save:onFile:). |
12288 (see ImageReader subclasses implementing save:onFile:). |
12289 May raise a signal, if the image cannot be written by the reader." |
12289 May raise a signal, if the image cannot be written by the reader." |
12290 |
12290 |
12291 |suffix readerClass| |
12291 |suffix readerClass| |
12320 |
12320 |
12321 "Modified: 30.6.1997 / 22:06:34 / cg" |
12321 "Modified: 30.6.1997 / 22:06:34 / cg" |
12322 ! |
12322 ! |
12323 |
12323 |
12324 saveOn:aFileName using:readerClass |
12324 saveOn:aFileName using:readerClass |
12325 "save the receiver using the representation class |
12325 "save the receiver using the representation class |
12326 (which is usually a concrete subclasses of ImageReader). |
12326 (which is usually a concrete subclasses of ImageReader). |
12327 May raise a signal, if the image cannot be written by the reader." |
12327 May raise a signal, if the image cannot be written by the reader." |
12328 |
12328 |
12329 ^ readerClass save:self onFile:aFileName |
12329 ^ readerClass save:self onFile:aFileName |
12330 |
12330 |
12378 If its a view or rootView, it must be completely visible (or have |
12378 If its a view or rootView, it must be completely visible (or have |
12379 the backingStore option turned on). Otherwise, only the clipped contents |
12379 the backingStore option turned on). Otherwise, only the clipped contents |
12380 is returned. This is a common helper for form-to-image conversion, |
12380 is returned. This is a common helper for form-to-image conversion, |
12381 and to read hardcopy images from the screen." |
12381 and to read hardcopy images from the screen." |
12382 |
12382 |
12383 | visType |
12383 | visType |
12384 x "{ Class: SmallInteger }" |
12384 x "{ Class: SmallInteger }" |
12385 y "{ Class: SmallInteger }" |
12385 y "{ Class: SmallInteger }" |
12386 w "{ Class: SmallInteger }" |
12386 w "{ Class: SmallInteger }" |
12387 h "{ Class: SmallInteger }" |
12387 h "{ Class: SmallInteger }" |
12388 dstIndex "{ Class: SmallInteger }" |
12388 dstIndex "{ Class: SmallInteger }" |
12389 srcIndex "{ Class: SmallInteger }" |
12389 srcIndex "{ Class: SmallInteger }" |
12390 srcRow "{ Class: SmallInteger }" |
12390 srcRow "{ Class: SmallInteger }" |
12391 dstRow "{ Class: SmallInteger }" |
12391 dstRow "{ Class: SmallInteger }" |
12392 inData tmpData usedPixels mapSize |
12392 inData tmpData usedPixels mapSize |
12393 map bytesPerLine |
12393 map bytesPerLine |
12394 bitOrder spaceBitsPerPixel |
12394 bitOrder spaceBitsPerPixel |
12395 info bitsPerPixelIn bytesPerLineIn |
12395 info bitsPerPixelIn bytesPerLineIn |
12396 bitsR "{ Class: SmallInteger }" |
12396 bitsR "{ Class: SmallInteger }" |
12397 bitsG "{ Class: SmallInteger }" |
12397 bitsG "{ Class: SmallInteger }" |
12398 bitsB "{ Class: SmallInteger }" |
12398 bitsB "{ Class: SmallInteger }" |
12399 maskR "{ Class: SmallInteger }" |
12399 maskR "{ Class: SmallInteger }" |
12400 maskG "{ Class: SmallInteger }" |
12400 maskG "{ Class: SmallInteger }" |
12407 shB2 "{ Class: SmallInteger }" |
12407 shB2 "{ Class: SmallInteger }" |
12408 r "{ Class: SmallInteger }" |
12408 r "{ Class: SmallInteger }" |
12409 g "{ Class: SmallInteger }" |
12409 g "{ Class: SmallInteger }" |
12410 b "{ Class: SmallInteger }" |
12410 b "{ Class: SmallInteger }" |
12411 word "{ Class: SmallInteger }" |
12411 word "{ Class: SmallInteger }" |
12412 lword |
12412 lword |
12413 device ddepth isMSB| |
12413 device ddepth isMSB| |
12414 |
12414 |
12415 depth := self depth. |
12415 depth := self depth. |
12416 bitsPerPixel := self bitsPerPixel. |
12416 bitsPerPixel := self bitsPerPixel. |
12417 |
12417 |
12418 device := aDrawable graphicsDevice. |
12418 device := aDrawable graphicsDevice. |
12419 |
12419 |
12420 (aDrawable isForm and:[aDrawable depth == 1]) ifTrue:[ |
12420 (aDrawable isForm and:[aDrawable depth == 1]) ifTrue:[ |
12421 "/ a monochrome bitmap ? |
12421 "/ a monochrome bitmap ? |
12422 visType := #StaticGray. |
12422 visType := #StaticGray. |
12423 ddepth := 1. |
12423 ddepth := 1. |
12424 ] ifFalse:[ |
12424 ] ifFalse:[ |
12425 (aDrawable isForm) ifFalse:[ |
12425 (aDrawable isForm) ifFalse:[ |
12426 " |
12426 " |
12427 get some attributes of the display device |
12427 get some attributes of the display device |
12428 " |
12428 " |
12429 visType := device visualType. |
12429 visType := device visualType. |
12430 ddepth := device depth. |
12430 ddepth := device depth. |
12431 ] ifTrue:[ |
12431 ] ifTrue:[ |
12432 ddepth := aDrawable depth. |
12432 ddepth := aDrawable depth. |
12433 visType := aDrawable photometric |
12433 visType := aDrawable photometric |
12434 ]. |
12434 ]. |
12435 ]. |
12435 ]. |
12436 |
12436 |
12437 "/ kludge for 15bit XFree server |
12437 "/ kludge for 15bit XFree server |
12438 ddepth == 15 ifTrue:[ |
12438 ddepth == 15 ifTrue:[ |
12439 ddepth := 16 |
12439 ddepth := 16 |
12440 ]. |
12440 ]. |
12441 |
12441 |
12442 aDrawable isForm ifTrue:[ |
12442 aDrawable isForm ifTrue:[ |
12443 photometric := aDrawable photometric. |
12443 photometric := aDrawable photometric. |
12444 samplesPerPixel := ddepth == 24 ifTrue:3 ifFalse:1. |
12444 samplesPerPixel := ddepth == 24 ifTrue:3 ifFalse:1. |
12445 bitsPerSample := ddepth == 24 ifTrue:#[8 8 8 ] ifFalse:[ByteArray with:bitsPerPixel]. |
12445 bitsPerSample := ddepth == 24 ifTrue:#[8 8 8 ] ifFalse:[ByteArray with:bitsPerPixel]. |
12446 ] ifFalse:[ |
12446 ] ifFalse:[ |
12447 (visType == #StaticGray) ifTrue:[ |
12447 (visType == #StaticGray) ifTrue:[ |
12448 (device blackpixel == 0) ifTrue:[ |
12448 (device blackpixel == 0) ifTrue:[ |
12449 photometric := #blackIs0 |
12449 photometric := #blackIs0 |
12450 ] ifFalse:[ |
12450 ] ifFalse:[ |
12451 photometric := #whiteIs0 |
12451 photometric := #whiteIs0 |
12452 ]. |
12452 ]. |
12453 samplesPerPixel := 1. |
12453 samplesPerPixel := 1. |
12454 bitsPerPixel := ddepth. |
12454 bitsPerPixel := ddepth. |
12455 bitsPerSample := ByteArray with:bitsPerPixel. |
12455 bitsPerSample := ByteArray with:bitsPerPixel. |
12456 ] ifFalse:[ |
12456 ] ifFalse:[ |
12457 ((visType == #PseudoColor) or:[(visType == #StaticColor) or:[visType == #GrayScale]]) ifTrue:[ |
12457 ((visType == #PseudoColor) or:[(visType == #StaticColor) or:[visType == #GrayScale]]) ifTrue:[ |
12458 photometric := #palette. |
12458 photometric := #palette. |
12459 samplesPerPixel := 1. |
12459 samplesPerPixel := 1. |
12460 bitsPerPixel := ddepth. |
12460 bitsPerPixel := ddepth. |
12461 bitsPerSample := ByteArray with:bitsPerPixel. |
12461 bitsPerSample := ByteArray with:bitsPerPixel. |
12462 ] ifFalse:[ |
12462 ] ifFalse:[ |
12463 ((visType == #TrueColor) or:[visType == #DirectColor]) ifTrue:[ |
12463 ((visType == #TrueColor) or:[visType == #DirectColor]) ifTrue:[ |
12464 photometric := #rgb. |
12464 photometric := #rgb. |
12465 samplesPerPixel := 3. |
12465 samplesPerPixel := 3. |
12466 "/ bitsPerPixel := depth. |
12466 "/ bitsPerPixel := depth. |
12467 "/ bitsPerSample := ByteArray with:device bitsRed |
12467 "/ bitsPerSample := ByteArray with:device bitsRed |
12468 "/ with:device bitsGreen |
12468 "/ with:device bitsGreen |
12469 "/ with:device bitsBlue |
12469 "/ with:device bitsBlue |
12470 bitsPerPixel := 24. |
12470 bitsPerPixel := 24. |
12471 bitsPerSample := #(8 8 8). |
12471 bitsPerSample := #(8 8 8). |
12472 ] ifFalse:[ |
12472 ] ifFalse:[ |
12473 self error:'screen visual not supported'. |
12473 self error:'screen visual not supported'. |
12474 ^ nil |
12474 ^ nil |
12475 ] |
12475 ] |
12476 ] |
12476 ] |
12477 ]. |
12477 ]. |
12478 ]. |
12478 ]. |
12479 |
12479 |
12480 " |
12480 " |
12481 dont know yet, how the display pads; assume worst case, |
12481 dont know yet, how the display pads; assume worst case, |
12482 offering enough space for 32 bit padding |
12482 offering enough space for 32 bit padding |
12483 " |
12483 " |
12484 w := width := aRectangle width. |
12484 w := width := aRectangle width. |
12485 h := height := aRectangle height. |
12485 h := height := aRectangle height. |
12486 x := aRectangle left. |
12486 x := aRectangle left. |
12490 a kludge: we dont know in advance how much we are going to need |
12490 a kludge: we dont know in advance how much we are going to need |
12491 (its too late when info is present ...) |
12491 (its too late when info is present ...) |
12492 " |
12492 " |
12493 spaceBitsPerPixel := bitsPerPixel. |
12493 spaceBitsPerPixel := bitsPerPixel. |
12494 (bitsPerPixel > 8) ifTrue:[ |
12494 (bitsPerPixel > 8) ifTrue:[ |
12495 spaceBitsPerPixel := 16. |
12495 spaceBitsPerPixel := 16. |
12496 (bitsPerPixel > 16) ifTrue:[ |
12496 (bitsPerPixel > 16) ifTrue:[ |
12497 spaceBitsPerPixel := 32. |
12497 spaceBitsPerPixel := 32. |
12498 (bitsPerPixel > 32) ifTrue:[ |
12498 (bitsPerPixel > 32) ifTrue:[ |
12499 spaceBitsPerPixel := bitsPerPixel. |
12499 spaceBitsPerPixel := bitsPerPixel. |
12500 ] |
12500 ] |
12501 ] |
12501 ] |
12502 ]. |
12502 ]. |
12503 |
12503 |
12504 bytesPerLine := (w * spaceBitsPerPixel + 31) // 32 * 4. |
12504 bytesPerLine := (w * spaceBitsPerPixel + 31) // 32 * 4. |
12505 "/ inData := ByteArray uninitializedNew:(bytesPerLine * height). |
12505 "/ inData := ByteArray uninitializedNew:(bytesPerLine * height). |
12506 inData := ByteArray new:(bytesPerLine * height). |
12506 inData := ByteArray new:(bytesPerLine * height). |
12507 |
12507 |
12508 " |
12508 " |
12509 get the pixels |
12509 get the pixels |
12510 " |
12510 " |
12511 aDrawable isForm ifTrue:[ |
12511 aDrawable isForm ifTrue:[ |
12512 info := device getBitsFromPixmapId:aDrawable id x:x y:y width:w height:h into:inData. |
12512 info := device getBitsFromPixmapId:aDrawable id x:x y:y width:w height:h into:inData. |
12513 ] ifFalse:[ |
12513 ] ifFalse:[ |
12514 info := device getBitsFromViewId:aDrawable id x:x y:y width:w height:h into:inData. |
12514 info := device getBitsFromViewId:aDrawable id x:x y:y width:w height:h into:inData. |
12515 ]. |
12515 ]. |
12516 |
12516 |
12517 bitsPerPixelIn := info at:#bitsPerPixel. |
12517 bitsPerPixelIn := info at:#bitsPerPixel. |
12518 |
12518 |
12519 isMSB := ((info at:#byteOrder) == #msbFirst). |
12519 isMSB := ((info at:#byteOrder) == #msbFirst). |
12522 "/ check if bitorder is what I like (msbFirst) |
12522 "/ check if bitorder is what I like (msbFirst) |
12523 "/ |
12523 "/ |
12524 "/ mhmh - thats not needed |
12524 "/ mhmh - thats not needed |
12525 |
12525 |
12526 bitsPerPixelIn < 8 ifTrue:[ |
12526 bitsPerPixelIn < 8 ifTrue:[ |
12527 bitOrder := info at:#bitOrder. |
12527 bitOrder := info at:#bitOrder. |
12528 bitOrder ~~ #msbFirst ifTrue:[ |
12528 bitOrder ~~ #msbFirst ifTrue:[ |
12529 inData |
12529 inData |
12530 expandPixels:8 |
12530 expandPixels:8 |
12531 width:(inData size) |
12531 width:(inData size) |
12532 height:1 |
12532 height:1 |
12533 into:inData |
12533 into:inData |
12534 mapping:(ImageReader reverseBits "TODO: reverseBitsForDepth:bitsPerPixelIn"). |
12534 mapping:(ImageReader reverseBits "TODO: reverseBitsForDepth:bitsPerPixelIn"). |
12535 ]. |
12535 ]. |
12536 ]. |
12536 ]. |
12537 |
12537 |
12538 " |
12538 " |
12539 check, if the devices padding is different .. |
12539 check, if the devices padding is different .. |
12540 or if the bitsPerPixels are different |
12540 or if the bitsPerPixels are different |
12544 |
12544 |
12545 maskR := info at:#redMask ifAbsent:0. |
12545 maskR := info at:#redMask ifAbsent:0. |
12546 maskG := info at:#greenMask ifAbsent:0. |
12546 maskG := info at:#greenMask ifAbsent:0. |
12547 maskB := info at:#blueMask ifAbsent:0. |
12547 maskB := info at:#blueMask ifAbsent:0. |
12548 |
12548 |
12549 ((bytesPerLine ~~ bytesPerLineIn) |
12549 ((bytesPerLine ~~ bytesPerLineIn) |
12550 or:[bitsPerPixelIn ~~ bitsPerPixel]) ifTrue:[ |
12550 or:[bitsPerPixelIn ~~ bitsPerPixel]) ifTrue:[ |
12551 tmpData := inData. |
12551 tmpData := inData. |
12552 inData := ByteArray uninitializedNew:(bytesPerLine * height). |
12552 inData := ByteArray uninitializedNew:(bytesPerLine * height). |
12553 |
12553 |
12554 srcRow := 1. |
12554 srcRow := 1. |
12555 dstRow := 1. |
12555 dstRow := 1. |
12556 |
12556 |
12557 bitsPerPixelIn ~~ bitsPerPixel ifTrue:[ |
12557 bitsPerPixelIn ~~ bitsPerPixel ifTrue:[ |
12558 "/ for now, only 32 -> 24 is supported |
12558 "/ for now, only 32 -> 24 is supported |
12559 |
12559 |
12560 maskR == 0 ifTrue:[ |
12560 maskR == 0 ifTrue:[ |
12561 bitsR := device bitsRed. |
12561 bitsR := device bitsRed. |
12562 bitsG := device bitsGreen. |
12562 bitsG := device bitsGreen. |
12563 bitsB := device bitsBlue. |
12563 bitsB := device bitsBlue. |
12564 maskR := (1 bitShift:bitsR) - 1. |
12564 maskR := (1 bitShift:bitsR) - 1. |
12565 maskG := (1 bitShift:bitsG) - 1. |
12565 maskG := (1 bitShift:bitsG) - 1. |
12566 maskB := (1 bitShift:bitsB) - 1. |
12566 maskB := (1 bitShift:bitsB) - 1. |
12567 shR := device shiftRed negated. |
12567 shR := device shiftRed negated. |
12568 shG := device shiftGreen negated. |
12568 shG := device shiftGreen negated. |
12569 shB := device shiftBlue negated. |
12569 shB := device shiftBlue negated. |
12570 ] ifFalse:[ |
12570 ] ifFalse:[ |
12571 shR := (maskR lowBit - 1) negated. |
12571 shR := (maskR lowBit - 1) negated. |
12572 bitsR := maskR highBit - maskR lowBit + 1. |
12572 bitsR := maskR highBit - maskR lowBit + 1. |
12573 maskR := maskR bitShift:shR. |
12573 maskR := maskR bitShift:shR. |
12574 shG := (maskG lowBit - 1) negated. |
12574 shG := (maskG lowBit - 1) negated. |
12575 bitsG := maskG highBit - maskG lowBit + 1. |
12575 bitsG := maskG highBit - maskG lowBit + 1. |
12576 maskG := maskG bitShift:shG. |
12576 maskG := maskG bitShift:shG. |
12577 shB := (maskB lowBit - 1) negated. |
12577 shB := (maskB lowBit - 1) negated. |
12578 bitsB := maskB highBit - maskB lowBit + 1. |
12578 bitsB := maskB highBit - maskB lowBit + 1. |
12579 maskB := maskB bitShift:shB. |
12579 maskB := maskB bitShift:shB. |
12580 ]. |
12580 ]. |
12581 shR2 := (8 - bitsR). |
12581 shR2 := (8 - bitsR). |
12582 shG2 := (8 - bitsG). |
12582 shG2 := (8 - bitsG). |
12583 shB2 := (8 - bitsB). |
12583 shB2 := (8 - bitsB). |
12584 |
12584 |
12585 ((bitsPerPixelIn == 32) and:[bitsPerPixel == 24]) ifTrue:[ |
12585 ((bitsPerPixelIn == 32) and:[bitsPerPixel == 24]) ifTrue:[ |
12586 "/ 'reformatting 32->24...' printNL. |
12586 "/ 'reformatting 32->24...' printNL. |
12587 1 to:h do:[:hi | |
12587 1 to:h do:[:hi | |
12588 srcIndex := srcRow. |
12588 srcIndex := srcRow. |
12589 dstIndex := dstRow. |
12589 dstIndex := dstRow. |
12590 |
12590 |
12591 1 to:w do:[:wi | |
12591 1 to:w do:[:wi | |
12592 lword := tmpData doubleWordAt:srcIndex MSB:isMSB. |
12592 lword := tmpData doubleWordAt:srcIndex MSB:isMSB. |
12593 r := (lword bitShift:shR) bitAnd:maskR. |
12593 r := (lword bitShift:shR) bitAnd:maskR. |
12594 g := (lword bitShift:shG) bitAnd:maskG. |
12594 g := (lword bitShift:shG) bitAnd:maskG. |
12595 b := (lword bitShift:shB) bitAnd:maskB. |
12595 b := (lword bitShift:shB) bitAnd:maskB. |
12596 |
12596 |
12597 inData at:dstIndex put:r. |
12597 inData at:dstIndex put:r. |
12598 inData at:dstIndex+1 put:g. |
12598 inData at:dstIndex+1 put:g. |
12599 inData at:dstIndex+2 put:b. |
12599 inData at:dstIndex+2 put:b. |
12600 srcIndex := srcIndex + 4. |
12600 srcIndex := srcIndex + 4. |
12601 dstIndex := dstIndex + 3. |
12601 dstIndex := dstIndex + 3. |
12602 ]. |
12602 ]. |
12603 dstRow := dstRow + bytesPerLine. |
12603 dstRow := dstRow + bytesPerLine. |
12604 srcRow := srcRow + bytesPerLineIn |
12604 srcRow := srcRow + bytesPerLineIn |
12605 ] |
12605 ] |
12606 ] ifFalse:[ |
12606 ] ifFalse:[ |
12607 ((bitsPerPixelIn == 16) and:[bitsPerPixel == 24]) ifTrue:[ |
12607 ((bitsPerPixelIn == 16) and:[bitsPerPixel == 24]) ifTrue:[ |
12608 "/ 'reformatting 16->24...' printNL. |
12608 "/ 'reformatting 16->24...' printNL. |
12609 1 to:h do:[:hi | |
12609 1 to:h do:[:hi | |
12610 srcIndex := srcRow. |
12610 srcIndex := srcRow. |
12611 dstIndex := dstRow. |
12611 dstIndex := dstRow. |
12612 |
12612 |
12613 1 to:w do:[:wi | |
12613 1 to:w do:[:wi | |
12614 word := tmpData wordAt:srcIndex MSB:isMSB. |
12614 word := tmpData wordAt:srcIndex MSB:isMSB. |
12615 r := (word bitShift:shR) bitAnd:maskR. |
12615 r := (word bitShift:shR) bitAnd:maskR. |
12616 g := (word bitShift:shG) bitAnd:maskG. |
12616 g := (word bitShift:shG) bitAnd:maskG. |
12617 b := (word bitShift:shB) bitAnd:maskB. |
12617 b := (word bitShift:shB) bitAnd:maskB. |
12618 |
12618 |
12619 inData at:dstIndex put:(r bitShift:shR2). |
12619 inData at:dstIndex put:(r bitShift:shR2). |
12620 inData at:dstIndex+1 put:(g bitShift:shG2). |
12620 inData at:dstIndex+1 put:(g bitShift:shG2). |
12621 inData at:dstIndex+2 put:(b bitShift:shB2). |
12621 inData at:dstIndex+2 put:(b bitShift:shB2). |
12622 |
12622 |
12623 srcIndex := srcIndex + 2. |
12623 srcIndex := srcIndex + 2. |
12624 dstIndex := dstIndex + 3. |
12624 dstIndex := dstIndex + 3. |
12625 ]. |
12625 ]. |
12626 dstRow := dstRow + bytesPerLine. |
12626 dstRow := dstRow + bytesPerLine. |
12627 srcRow := srcRow + bytesPerLineIn |
12627 srcRow := srcRow + bytesPerLineIn |
12628 ] |
12628 ] |
12629 ] ifFalse:[ |
12629 ] ifFalse:[ |
12630 ('Image [warning]: unsupported depth combination: ' , bitsPerPixelIn printString , ' -> ' , |
12630 ('Image [warning]: unsupported depth combination: ' , bitsPerPixelIn printString , ' -> ' , |
12631 bitsPerPixel printString) errorPrintCR. |
12631 bitsPerPixel printString) errorPrintCR. |
12632 self shouldImplement. |
12632 self shouldImplement. |
12633 ^ nil |
12633 ^ nil |
12634 ] |
12634 ] |
12635 ]. |
12635 ]. |
12636 ] ifFalse:[ |
12636 ] ifFalse:[ |
12637 "/ |
12637 "/ |
12638 "/ repad in the buffer |
12638 "/ repad in the buffer |
12639 "/ |
12639 "/ |
12640 1 to:h do:[:hi | |
12640 1 to:h do:[:hi | |
12641 inData replaceFrom:dstRow to:(dstRow + bytesPerLine - 1) |
12641 inData replaceFrom:dstRow to:(dstRow + bytesPerLine - 1) |
12642 with:tmpData startingAt:srcRow. |
12642 with:tmpData startingAt:srcRow. |
12643 dstRow := dstRow + bytesPerLine. |
12643 dstRow := dstRow + bytesPerLine. |
12644 srcRow := srcRow + bytesPerLineIn |
12644 srcRow := srcRow + bytesPerLineIn |
12645 ] |
12645 ] |
12646 ] |
12646 ] |
12647 ] ifFalse:[ |
12647 ] ifFalse:[ |
12648 (bytesPerLine * height) ~~ inData size ifTrue:[ |
12648 (bytesPerLine * height) ~~ inData size ifTrue:[ |
12649 tmpData := inData. |
12649 tmpData := inData. |
12650 inData := ByteArray uninitializedNew:(bytesPerLine * height). |
12650 inData := ByteArray uninitializedNew:(bytesPerLine * height). |
12651 inData replaceFrom:1 to:bytesPerLine * height with:tmpData startingAt:1 |
12651 inData replaceFrom:1 to:bytesPerLine * height with:tmpData startingAt:1 |
12652 ] |
12652 ] |
12653 ]. |
12653 ]. |
12654 self bits:inData. |
12654 self bits:inData. |
12655 |
12655 |
12656 "/ |
12656 "/ |
12657 "/ if not #palette we are done, the pixel values are the rgb/grey values |
12657 "/ if not #palette we are done, the pixel values are the rgb/grey values |
12658 "/ |
12658 "/ |
12659 photometric == #palette ifTrue:[ |
12659 photometric == #palette ifTrue:[ |
12660 "/ |
12660 "/ |
12661 "/ what we have now are the color numbers - still need the r/g/b values. |
12661 "/ what we have now are the color numbers - still need the r/g/b values. |
12662 "/ find out, which colors are in the picture |
12662 "/ find out, which colors are in the picture |
12663 "/ |
12663 "/ |
12664 usedPixels := inData usedValues. |
12664 usedPixels := inData usedValues. |
12665 mapSize := usedPixels max + 1. |
12665 mapSize := usedPixels max + 1. |
12666 |
12666 |
12667 "get the palette" |
12667 "get the palette" |
12668 map := Array new:mapSize. |
12668 map := Array new:mapSize. |
12669 usedPixels do:[:colorIndex | |
12669 usedPixels do:[:colorIndex | |
12670 |i| |
12670 |i| |
12671 |
12671 |
12672 i := colorIndex + 1. |
12672 i := colorIndex + 1. |
12673 device getRGBFrom:colorIndex into:[:r :g :b | |
12673 device getRGBFrom:colorIndex into:[:r :g :b | |
12674 map at:i put:(Color red:r green:g blue:b) |
12674 map at:i put:(Color red:r green:g blue:b) |
12675 ] |
12675 ] |
12676 ]. |
12676 ]. |
12677 self setColorMap:map. |
12677 self setColorMap:map. |
12678 ]. |
12678 ]. |
12679 |
12679 |
12680 "Modified: / 9.1.1998 / 21:32:36 / stefan" |
12680 "Modified: / 9.1.1998 / 21:32:36 / stefan" |
12681 "Modified: / 7.2.1998 / 18:23:07 / cg" |
12681 "Modified: / 7.2.1998 / 18:23:07 / cg" |
12682 ! |
12682 ! |
12685 "read an image from the display screen. |
12685 "read an image from the display screen. |
12686 WARNING: this temporarily grabs the display |
12686 WARNING: this temporarily grabs the display |
12687 it may not work from within a buttonMotion |
12687 it may not work from within a buttonMotion |
12688 (use #fromScreen:on:grab: with a false grabArg then)." |
12688 (use #fromScreen:on:grab: with a false grabArg then)." |
12689 |
12689 |
12690 ^ self |
12690 ^ self |
12691 fromScreen:aRectangle |
12691 fromScreen:aRectangle |
12692 on:Screen current |
12692 on:Screen current |
12693 grab:true |
12693 grab:true |
12694 |
12694 |
12695 "Modified: 26.3.1997 / 10:43:34 / cg" |
12695 "Modified: 26.3.1997 / 10:43:34 / cg" |
12696 ! |
12696 ! |
12697 |
12697 |
12698 fromScreen:aRectangle on:aDevice |
12698 fromScreen:aRectangle on:aDevice |
12699 "read an image from aDevices display screen. |
12699 "read an image from aDevices display screen. |
12700 Since I have no other displays, only the MonoChrome, StaticGrey |
12700 Since I have no other displays, only the MonoChrome, StaticGrey |
12701 and PseudoColor cases have been tested ... |
12701 and PseudoColor cases have been tested ... |
12702 (especially True- and DirectColor may be wrong). |
12702 (especially True- and DirectColor may be wrong). |
12703 Late note: 24bit rgb now also works. |
12703 Late note: 24bit rgb now also works. |
12704 WARNING: this temporarily grabs the display |
12704 WARNING: this temporarily grabs the display |
12705 it may not work from within a buttonMotion |
12705 it may not work from within a buttonMotion |
12706 (use #fromScreen:on:grab: with a false grabArg then)." |
12706 (use #fromScreen:on:grab: with a false grabArg then)." |
12707 |
12707 |
12708 ^ self |
12708 ^ self |
12709 fromScreen:aRectangle |
12709 fromScreen:aRectangle |
12710 on:aDevice |
12710 on:aDevice |
12711 grab:true |
12711 grab:true |
12712 |
12712 |
12713 " |
12713 " |
12714 Image fromScreen:((0 @ 0) corner:(100 @ 100)) on:Display |
12714 Image fromScreen:((0 @ 0) corner:(100 @ 100)) on:Display |
12715 Image fromScreen:((0 @ 0) corner:(500 @ 500)) on:Display |
12715 Image fromScreen:((0 @ 0) corner:(500 @ 500)) on:Display |
12721 fromScreen:aRectangle on:aDevice grab:doGrab |
12721 fromScreen:aRectangle on:aDevice grab:doGrab |
12722 "read an image from aDevices display screen. |
12722 "read an image from aDevices display screen. |
12723 If the doGrab argument is true, the display |
12723 If the doGrab argument is true, the display |
12724 is grabbed (i.e. blocked for others) and a camera cursor is |
12724 is grabbed (i.e. blocked for others) and a camera cursor is |
12725 shown while the readout is done. |
12725 shown while the readout is done. |
12726 Since I have no other displays, only the MonoChrome, StaticGrey |
12726 Since I have no other displays, only the MonoChrome, StaticGrey |
12727 and PseudoColor cases have been tested ... |
12727 and PseudoColor cases have been tested ... |
12728 (especially True- and DirectColor may be wrong). |
12728 (especially True- and DirectColor may be wrong). |
12729 Late note: 24bit rgb now also works. |
12729 Late note: 24bit rgb now also works. |
12730 WARNING: with doGrab true, this temporarily grabs the display |
12730 WARNING: with doGrab true, this temporarily grabs the display |
12731 and it may not work from within a buttonMotion |
12731 and it may not work from within a buttonMotion |
12732 (use with a false grabArg then)." |
12732 (use with a false grabArg then)." |
12733 |
12733 |
12734 |curs rootView prevGrab| |
12734 |curs rootView prevGrab| |
12735 |
12735 |
12736 "/ doGrab ifTrue:[ |cid| |
12736 "/ doGrab ifTrue:[ |cid| |
12737 "/ curs := Cursor sourceForm:(Image fromFile:'bitmaps/Camera.xbm') |
12737 "/ curs := Cursor sourceForm:(Image fromFile:'bitmaps/Camera.xbm') |
12745 " |
12745 " |
12746 actually have to grabServer ... but thats not yet available |
12746 actually have to grabServer ... but thats not yet available |
12747 " |
12747 " |
12748 rootView := aDevice rootView. |
12748 rootView := aDevice rootView. |
12749 doGrab ifTrue:[ |
12749 doGrab ifTrue:[ |
12750 prevGrab := aDevice activePointerGrab. |
12750 prevGrab := aDevice activePointerGrab. |
12751 aDevice grabPointerInView:rootView withCursor:curs. |
12751 aDevice grabPointerInView:rootView withCursor:curs. |
12752 ]. |
12752 ]. |
12753 |
12753 |
12754 " |
12754 " |
12755 get the pixels |
12755 get the pixels |
12756 " |
12756 " |
12757 [ |
12757 [ |
12758 self from:rootView in:aRectangle. |
12758 self from:rootView in:aRectangle. |
12759 ] ensure:[ |
12759 ] ensure:[ |
12760 doGrab ifTrue:[ |
12760 doGrab ifTrue:[ |
12761 aDevice ungrabPointer. |
12761 aDevice ungrabPointer. |
12762 prevGrab notNil ifTrue:[ |
12762 prevGrab notNil ifTrue:[ |
12763 aDevice grabPointerInView:prevGrab. |
12763 aDevice grabPointerInView:prevGrab. |
12764 ] |
12764 ] |
12765 ] |
12765 ] |
12766 ] |
12766 ] |
12767 |
12767 |
12768 " |
12768 " |
12769 Image fromScreen:((100@100) corner:(200@200)) on:Display grab:false |
12769 Image fromScreen:((100@100) corner:(200@200)) on:Display grab:false |
12770 Image fromScreen:((100@100) corner:(200@200)) on:Display grab:true |
12770 Image fromScreen:((100@100) corner:(200@200)) on:Display grab:true |
12784 visType := aDevice visualType. |
12784 visType := aDevice visualType. |
12785 depth := aDevice depth. |
12785 depth := aDevice depth. |
12786 |
12786 |
12787 "/ kludge for 15bit XFree server |
12787 "/ kludge for 15bit XFree server |
12788 depth == 15 ifTrue:[ |
12788 depth == 15 ifTrue:[ |
12789 depth := 16 |
12789 depth := 16 |
12790 ]. |
12790 ]. |
12791 |
12791 |
12792 (visType == #StaticGray) ifTrue:[ |
12792 (visType == #StaticGray) ifTrue:[ |
12793 (aDevice blackpixel == 0) ifTrue:[ |
12793 (aDevice blackpixel == 0) ifTrue:[ |
12794 photometric := #blackIs0 |
12794 photometric := #blackIs0 |
12795 ] ifFalse:[ |
12795 ] ifFalse:[ |
12796 photometric := #whiteIs0 |
12796 photometric := #whiteIs0 |
12797 ]. |
12797 ]. |
12798 samplesPerPixel := 1. |
12798 samplesPerPixel := 1. |
12799 bitsPerPixel := depth. |
12799 bitsPerPixel := depth. |
12800 bitsPerSample := ByteArray with:bitsPerPixel. |
12800 bitsPerSample := ByteArray with:bitsPerPixel. |
12801 " |
12801 " |
12802 were done, the pixel values are the grey values |
12802 were done, the pixel values are the grey values |
12803 " |
12803 " |
12804 ^ self |
12804 ^ self |
12805 ]. |
12805 ]. |
12806 |
12806 |
12807 ((visType == #TrueColor) or:[visType == #DirectColor]) ifTrue:[ |
12807 ((visType == #TrueColor) or:[visType == #DirectColor]) ifTrue:[ |
12808 photometric := #rgb. |
12808 photometric := #rgb. |
12809 samplesPerPixel := 3. |
12809 samplesPerPixel := 3. |
12810 |
12810 |
12811 "/ for now - only support 24bit TrueColor |
12811 "/ for now - only support 24bit TrueColor |
12812 depth ~~ 24 ifTrue:[ |
12812 depth ~~ 24 ifTrue:[ |
12813 'IMAGE: unsupported display depth' errorPrintCR. |
12813 'IMAGE: unsupported display depth' errorPrintCR. |
12814 ]. |
12814 ]. |
12815 "/ bitsPerPixel := depth. |
12815 "/ bitsPerPixel := depth. |
12816 "/ bitsPerSample := ByteArray with:aDevice bitsRed |
12816 "/ bitsPerSample := ByteArray with:aDevice bitsRed |
12817 "/ with:aDevice bitsGreen |
12817 "/ with:aDevice bitsGreen |
12818 "/ with:aDevice bitsBlue |
12818 "/ with:aDevice bitsBlue |
12819 bitsPerPixel := 24. |
12819 bitsPerPixel := 24. |
12820 bitsPerSample := #[8 8 8]. |
12820 bitsPerSample := #[8 8 8]. |
12821 " |
12821 " |
12822 were done, the pixel values are the rgb values |
12822 were done, the pixel values are the rgb values |
12823 " |
12823 " |
12824 ^ self |
12824 ^ self |
12825 ]. |
12825 ]. |
12826 |
12826 |
12827 ((visType ~~ #PseudoColor) |
12827 ((visType ~~ #PseudoColor) |
12828 and:[(visType ~~ #StaticColor) |
12828 and:[(visType ~~ #StaticColor) |
12829 and:[visType ~~ #GrayScale]]) ifTrue:[ |
12829 and:[visType ~~ #GrayScale]]) ifTrue:[ |
12830 self error:'screen visual not supported'. |
12830 self error:'screen visual not supported'. |
12831 ^ nil |
12831 ^ nil |
12832 ]. |
12832 ]. |
12833 |
12833 |
12834 photometric := #palette. |
12834 photometric := #palette. |
12835 samplesPerPixel := 1. |
12835 samplesPerPixel := 1. |
12836 bitsPerPixel := depth. |
12836 bitsPerPixel := depth. |
12845 ! ! |
12845 ! ! |
12846 |
12846 |
12847 !Image class methodsFor:'documentation'! |
12847 !Image class methodsFor:'documentation'! |
12848 |
12848 |
12849 version |
12849 version |
12850 ^ '$Header: /cvs/stx/stx/libview/Image.st,v 1.386 2006-09-18 19:49:19 cg Exp $' |
12850 ^ '$Header: /cvs/stx/stx/libview/Image.st,v 1.387 2007-01-24 13:40:55 cg Exp $' |
12851 ! ! |
12851 ! ! |
12852 |
12852 |
12853 Image initialize! |
12853 Image initialize! |