186 |
186 |
187 "Created: 24.4.1997 / 15:49:42 / cg" |
187 "Created: 24.4.1997 / 15:49:42 / cg" |
188 ! ! |
188 ! ! |
189 |
189 |
190 !Depth8Image methodsFor:'converting'! |
190 !Depth8Image methodsFor:'converting'! |
|
191 |
|
192 fromImage:anImage |
|
193 "setup the receiver from another image. |
|
194 The code here is tuned for depth 1, 2 and 4 source images; |
|
195 other conversions are done in the superclasses fallBack method." |
|
196 |
|
197 |srcBytesPerRow srcBuffer dstBuffer srcBytes srcIdx dstIdx |
|
198 srcDepth map| |
|
199 |
|
200 srcDepth := anImage depth. |
|
201 (#(1 2 4) includes:srcDepth) ifFalse:[ |
|
202 ^ super fromImage:anImage |
|
203 ]. |
|
204 |
|
205 width := anImage width. |
|
206 height := anImage height. |
|
207 bytes := ByteArray uninitializedNew:(width * height). |
|
208 bitsPerSample := self bitsPerSample. |
|
209 samplesPerPixel := self samplesPerPixel. |
|
210 self colormapFromImage:anImage. |
|
211 |
|
212 colorMap isNil ifTrue:[ |
|
213 "/ if source has no colorMap, more work is needed ... |
|
214 map := #( |
|
215 #[0 16rFF] |
|
216 #[0 16r55 16rAA 16rFF] |
|
217 nil |
|
218 #[16r00 16r11 16r22 16r33 16r44 16r55 16r66 16r77 |
|
219 16r88 16r99 16rAA 16rBB 16rCC 16rDD 16rEE 16rFF] |
|
220 ) at:srcDepth. |
|
221 ]. |
|
222 |
|
223 self mask:anImage mask. |
|
224 |
|
225 "/ only expand & translate pixels |
|
226 |
|
227 srcBytes := anImage bits. |
|
228 srcBytesPerRow := anImage bytesPerRow. |
|
229 srcBuffer := ByteArray new:srcBytesPerRow. |
|
230 |
|
231 dstBuffer := ByteArray new:width. |
|
232 srcIdx := 1. |
|
233 dstIdx := 1. |
|
234 1 to:height do:[:hi | |
|
235 srcBuffer replaceFrom:1 to:srcBytesPerRow with:srcBytes startingAt:srcIdx. |
|
236 srcBuffer expandPixels:srcDepth width:width height:1 into:dstBuffer |
|
237 mapping:map. |
|
238 bytes replaceFrom:dstIdx to:dstIdx+width-1 with:dstBuffer startingAt:1. |
|
239 dstIdx := dstIdx + width. |
|
240 srcIdx := srcIdx + srcBytesPerRow. |
|
241 ] |
|
242 |
|
243 " |
|
244 |i1 i2 i4 i8 i16 i24| |
|
245 |
|
246 i1 := Image fromFile:'bitmaps/SBrowser.xbm'. |
|
247 i2 := Depth2Image fromImage:i1. |
|
248 i4 := Depth4Image fromImage:i1. |
|
249 |
|
250 i8 := Depth8Image fromImage:i1. |
|
251 i8 inspect. |
|
252 i8 := Depth8Image fromImage:i2. |
|
253 i8 inspect. |
|
254 i8 := Depth8Image fromImage:i4. |
|
255 i8 inspect. |
|
256 " |
|
257 |
|
258 "Modified: 24.4.1997 / 14:01:14 / cg" |
|
259 ! ! |
|
260 |
|
261 !Depth8Image methodsFor:'converting images'! |
191 |
262 |
192 anyImageAsPseudoFormOn:aDevice |
263 anyImageAsPseudoFormOn:aDevice |
193 "return a pseudoForm from the palette picture. |
264 "return a pseudoForm from the palette picture. |
194 The main work is in color reduction, when not all colors can be aquired. |
265 The main work is in color reduction, when not all colors can be aquired. |
195 This method works for any photometric." |
266 This method works for any photometric." |
546 |
617 |
547 "Modified: 15.10.1997 / 01:48:20 / cg" |
618 "Modified: 15.10.1997 / 01:48:20 / cg" |
548 "Created: 19.10.1997 / 04:57:05 / cg" |
619 "Created: 19.10.1997 / 04:57:05 / cg" |
549 ! |
620 ! |
550 |
621 |
551 fromImage:anImage |
622 anyImageAsTrueColorFormOn:aDevice |
552 "setup the receiver from another image. |
623 "return a true-color device-form for the receiver. |
553 The code here is tuned for depth 1, 2 and 4 source images; |
|
554 other conversions are done in the superclasses fallBack method." |
|
555 |
|
556 |srcBytesPerRow srcBuffer dstBuffer srcBytes srcIdx dstIdx |
|
557 srcDepth map| |
|
558 |
|
559 srcDepth := anImage depth. |
|
560 (#(1 2 4) includes:srcDepth) ifFalse:[ |
|
561 ^ super fromImage:anImage |
|
562 ]. |
|
563 |
|
564 width := anImage width. |
|
565 height := anImage height. |
|
566 bytes := ByteArray uninitializedNew:(width * height). |
|
567 bitsPerSample := self bitsPerSample. |
|
568 samplesPerPixel := self samplesPerPixel. |
|
569 self colormapFromImage:anImage. |
|
570 |
|
571 colorMap isNil ifTrue:[ |
|
572 "/ if source has no colorMap, more work is needed ... |
|
573 map := #( |
|
574 #[0 16rFF] |
|
575 #[0 16r55 16rAA 16rFF] |
|
576 nil |
|
577 #[16r00 16r11 16r22 16r33 16r44 16r55 16r66 16r77 |
|
578 16r88 16r99 16rAA 16rBB 16rCC 16rDD 16rEE 16rFF] |
|
579 ) at:srcDepth. |
|
580 ]. |
|
581 |
|
582 self mask:anImage mask. |
|
583 |
|
584 "/ only expand & translate pixels |
|
585 |
|
586 srcBytes := anImage bits. |
|
587 srcBytesPerRow := anImage bytesPerRow. |
|
588 srcBuffer := ByteArray new:srcBytesPerRow. |
|
589 |
|
590 dstBuffer := ByteArray new:width. |
|
591 srcIdx := 1. |
|
592 dstIdx := 1. |
|
593 1 to:height do:[:hi | |
|
594 srcBuffer replaceFrom:1 to:srcBytesPerRow with:srcBytes startingAt:srcIdx. |
|
595 srcBuffer expandPixels:srcDepth width:width height:1 into:dstBuffer |
|
596 mapping:map. |
|
597 bytes replaceFrom:dstIdx to:dstIdx+width-1 with:dstBuffer startingAt:1. |
|
598 dstIdx := dstIdx + width. |
|
599 srcIdx := srcIdx + srcBytesPerRow. |
|
600 ] |
|
601 |
|
602 " |
|
603 |i1 i2 i4 i8 i16 i24| |
|
604 |
|
605 i1 := Image fromFile:'bitmaps/SBrowser.xbm'. |
|
606 i2 := Depth2Image fromImage:i1. |
|
607 i4 := Depth4Image fromImage:i1. |
|
608 |
|
609 i8 := Depth8Image fromImage:i1. |
|
610 i8 inspect. |
|
611 i8 := Depth8Image fromImage:i2. |
|
612 i8 inspect. |
|
613 i8 := Depth8Image fromImage:i4. |
|
614 i8 inspect. |
|
615 " |
|
616 |
|
617 "Modified: 24.4.1997 / 14:01:14 / cg" |
|
618 ! ! |
|
619 |
|
620 !Depth8Image methodsFor:'converting palette images'! |
|
621 |
|
622 asGray8FormOn:aDevice |
|
623 "return an 8-bit greyForm from the 8-bit receiver image. |
|
624 Redefined, since only a translation has to be done here." |
|
625 |
|
626 |greyBits map |
|
627 mapSize "{ Class: SmallInteger }"| |
|
628 |
|
629 greyBits := ByteArray uninitializedNew:(width * height). |
|
630 |
|
631 map := ByteArray uninitializedNew:256. |
|
632 |
|
633 1 to:256 do:[:i | |
|
634 map at:i put:((self colorFromValue:(i-1)) brightness * 255) rounded |
|
635 ]. |
|
636 |
|
637 "/ mapSize := colorMap size. |
|
638 "/ |
|
639 "/ 1 to:mapSize do:[:i | |
|
640 "/ map at:i put:((colorMap at:i) brightness * 255) rounded |
|
641 "/ ]. |
|
642 |
|
643 bytes expandPixels:8 "xlate only" |
|
644 width:width |
|
645 height:height |
|
646 into:greyBits |
|
647 mapping:map. |
|
648 |
|
649 ^ self makeDeviceGrayPixmapOn:aDevice depth:8 fromArray:greyBits |
|
650 |
|
651 "Modified: 10.6.1996 / 20:10:14 / cg" |
|
652 "Created: 14.6.1996 / 15:23:09 / cg" |
|
653 ! |
|
654 |
|
655 asGrayFormOn:aDevice |
|
656 "get a gray device form. |
|
657 Redefined, since we can do it with simple translate, |
|
658 if the depth matches my depth." |
|
659 |
|
660 (aDevice visualType == #StaticGray) ifTrue:[ |
|
661 (aDevice depth == 8) ifTrue:[ |
|
662 ^ self asGray8FormOn:aDevice |
|
663 ]. |
|
664 ]. |
|
665 ^ super asGrayFormOn:aDevice |
|
666 |
|
667 "Created: 10.6.1996 / 18:51:19 / cg" |
|
668 "Modified: 10.6.1996 / 18:54:36 / cg" |
|
669 ! |
|
670 |
|
671 greyImageAsPseudoFormOn:aDevice |
|
672 "return a pseudoForm from the gray picture. The main work is |
|
673 in color reduction, when not all colors can be aquired." |
|
674 |
|
675 ^ self anyImageAsPseudoFormOn:aDevice |
|
676 |
|
677 "Modified: 19.10.1997 / 04:57:39 / cg" |
|
678 "Created: 19.10.1997 / 04:58:41 / cg" |
|
679 ! |
|
680 |
|
681 paletteImageAsPseudoFormOn:aDevice |
|
682 "return a pseudoForm from the palette picture. The main work is |
|
683 in color reduction, when not all colors can be aquired." |
|
684 |
|
685 ^ self anyImageAsPseudoFormOn:aDevice |
|
686 |
|
687 "Modified: 19.10.1997 / 04:57:39 / cg" |
|
688 ! |
|
689 |
|
690 paletteImageAsTrueColorFormOn:aDevice |
|
691 "return a true-color device-form for the palette-image receiver. |
|
692 Supports true color devices with depths: 8, 16, 24 and 32" |
624 Supports true color devices with depths: 8, 16, 24 and 32" |
693 |
625 |
694 |depth |
626 |depth |
695 nColors "{ Class: SmallInteger }" |
|
696 colorValues |
627 colorValues |
697 scaleRed scaleGreen scaleBlue redShift greenShift blueShift |
|
698 form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel |
628 form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel |
699 usedDevicePadding usedDeviceBytesPerRow padd n| |
629 usedDevicePadding usedDeviceBytesPerRow padd n| |
700 |
630 |
701 depth := aDevice depth. |
631 depth := aDevice depth. |
702 |
632 |
703 "/ gather r/g/b values for all colors in the map ... |
633 "/ gather r/g/b values for all colors in the map ... |
704 |
634 |
705 nColors := colorMap size. |
635 colorValues := self rgbColormapFor:aDevice. |
706 |
|
707 "/ precompute scales to map from 0..100 into devices range |
|
708 "/ (this may be different for the individual components) |
|
709 |
|
710 scaleRed := ((1 bitShift:aDevice bitsRed) - 1) / 100. |
|
711 scaleGreen := ((1 bitShift:aDevice bitsGreen) - 1) / 100. |
|
712 scaleBlue := ((1 bitShift:aDevice bitsBlue) - 1) / 100. |
|
713 redShift := aDevice shiftRed. |
|
714 greenShift := aDevice shiftGreen. |
|
715 blueShift := aDevice shiftBlue. |
|
716 |
|
717 colorValues := Array uninitializedNew:nColors. |
|
718 |
|
719 1 to:nColors do:[:index | |
|
720 |clr rv gv bv v "{ Class: SmallInteger }" | |
|
721 |
|
722 clr := colorMap at:index. |
|
723 clr notNil ifTrue:[ |
|
724 rv := (clr red * scaleRed) rounded. |
|
725 gv := (clr green * scaleGreen) rounded. |
|
726 bv := (clr blue * scaleBlue) rounded. |
|
727 |
|
728 v := rv bitShift:redShift. |
|
729 v := v bitOr:(gv bitShift:greenShift). |
|
730 v := v bitOr:(bv bitShift:blueShift). |
|
731 colorValues at:index put:v. |
|
732 "/ clr print. ' ' print. |
|
733 "/ rv print. ' ' print. gv print. ' ' print. bv print. ' ' print. |
|
734 "/ ' -> ' print. v printNL. |
|
735 |
|
736 ] |
|
737 ]. |
|
738 |
636 |
739 bestFormat := self bestSupportedImageFormatFor:aDevice. |
637 bestFormat := self bestSupportedImageFormatFor:aDevice. |
740 usedDeviceDepth := bestFormat at:#depth. |
638 usedDeviceDepth := bestFormat at:#depth. |
741 usedDeviceBitsPerPixel := bestFormat at:#bitsPerPixel. |
639 usedDeviceBitsPerPixel := bestFormat at:#bitsPerPixel. |
742 usedDevicePadding := bestFormat at:#padding. |
640 usedDevicePadding := bestFormat at:#padding. |
758 && __isArray(colorValues) |
656 && __isArray(colorValues) |
759 && __isByteArray(_INST(bytes)) |
657 && __isByteArray(_INST(bytes)) |
760 && __isByteArray(imageBits)) { |
658 && __isByteArray(imageBits)) { |
761 int r,p; |
659 int r,p; |
762 int x, y, w, h, nPix; |
660 int x, y, w, h, nPix; |
|
661 unsigned short pixels[256]; |
763 |
662 |
764 unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element; |
663 unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element; |
765 unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element; |
664 unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element; |
766 OBJ *ap = __ArrayInstPtr(colorValues)->a_element; |
665 OBJ *ap = __ArrayInstPtr(colorValues)->a_element; |
|
666 |
|
667 nPix = __arraySize(colorValues); |
|
668 for (p=0; p<nPix; p++) { |
|
669 pixels[p] = __intVal(ap[p]); |
|
670 } |
767 |
671 |
768 w = __intVal(_INST(width)); |
672 w = __intVal(_INST(width)); |
769 h = __intVal(_INST(height)); |
673 h = __intVal(_INST(height)); |
770 r = w; |
674 r = w; |
771 p = __intVal(padd); |
675 p = __intVal(padd); |
772 nPix = w * h; |
676 nPix = w * h; |
773 while (nPix-- > 0) { |
677 |
|
678 while (nPix > 0) { |
774 unsigned idx, v; |
679 unsigned idx, v; |
775 OBJ clr; |
680 |
|
681 while (r > 4) { |
|
682 idx = ((unsigned int *)srcPtr)[0]; |
|
683 #ifdef MSBFIRST |
|
684 v = pixels[(idx >> 24) & 0xFF]; |
|
685 ((short *)dstPtr)[0] = v; |
|
686 v = pixels[(idx >> 16) & 0xFF]; |
|
687 ((short *)dstPtr)[1] = v; |
|
688 v = pixels[(idx >> 8) & 0xFF]; |
|
689 ((short *)dstPtr)[2] = v; |
|
690 v = pixels[idx & 0xFF]; |
|
691 ((short *)dstPtr)[3] = v; |
|
692 #else |
|
693 v = pixels[idx & 0xFF]; |
|
694 idx >>= 8; |
|
695 |
|
696 dstPtr[0] = (v>>8) & 0xFF; |
|
697 dstPtr[1] = (v) & 0xFF; |
|
698 |
|
699 v = pixels[idx & 0xFF]; |
|
700 idx >>= 8; |
|
701 |
|
702 dstPtr[2] = (v>>8) & 0xFF; |
|
703 dstPtr[3] = (v) & 0xFF; |
|
704 |
|
705 v = pixels[idx & 0xFF]; |
|
706 idx >>= 8; |
|
707 |
|
708 dstPtr[4] = (v>>8) & 0xFF; |
|
709 dstPtr[5] = (v) & 0xFF; |
|
710 v = pixels[idx & 0xFF]; |
|
711 |
|
712 dstPtr[6] = (v>>8) & 0xFF; |
|
713 dstPtr[7] = (v) & 0xFF; |
|
714 #endif |
|
715 r -= 4; |
|
716 dstPtr += 8; |
|
717 nPix -= 4; |
|
718 srcPtr +=4; |
|
719 } |
|
720 |
|
721 nPix--; |
776 |
722 |
777 idx = *srcPtr++; |
723 idx = *srcPtr++; |
778 clr = ap[idx]; |
724 v = pixels[idx]; |
779 v = __intVal(clr); |
|
780 #ifdef MSBFIRST |
725 #ifdef MSBFIRST |
781 ((short *)dstPtr)[0] = v; |
726 ((short *)dstPtr)[0] = v; |
782 #else |
727 #else |
783 dstPtr[0] = (v>>8) & 0xFF; |
728 dstPtr[0] = (v>>8) & 0xFF; |
784 dstPtr[1] = (v) & 0xFF; |
729 dstPtr[1] = (v) & 0xFF; |
953 |
898 |
954 ^ form |
899 ^ form |
955 |
900 |
956 "Created: 20.10.1995 / 22:05:10 / cg" |
901 "Created: 20.10.1995 / 22:05:10 / cg" |
957 "Modified: 21.10.1995 / 19:30:26 / cg" |
902 "Modified: 21.10.1995 / 19:30:26 / cg" |
|
903 ! |
|
904 |
|
905 asGray8FormOn:aDevice |
|
906 "return an 8-bit greyForm from the 8-bit receiver image. |
|
907 Redefined, since only a translation has to be done here." |
|
908 |
|
909 |greyBits map |
|
910 mapSize "{ Class: SmallInteger }"| |
|
911 |
|
912 greyBits := ByteArray uninitializedNew:(width * height). |
|
913 |
|
914 map := ByteArray uninitializedNew:256. |
|
915 |
|
916 1 to:256 do:[:i | |
|
917 map at:i put:((self colorFromValue:(i-1)) brightness * 255) rounded |
|
918 ]. |
|
919 |
|
920 "/ mapSize := colorMap size. |
|
921 "/ |
|
922 "/ 1 to:mapSize do:[:i | |
|
923 "/ map at:i put:((colorMap at:i) brightness * 255) rounded |
|
924 "/ ]. |
|
925 |
|
926 bytes expandPixels:8 "xlate only" |
|
927 width:width |
|
928 height:height |
|
929 into:greyBits |
|
930 mapping:map. |
|
931 |
|
932 ^ self makeDeviceGrayPixmapOn:aDevice depth:8 fromArray:greyBits |
|
933 |
|
934 "Modified: 10.6.1996 / 20:10:14 / cg" |
|
935 "Created: 14.6.1996 / 15:23:09 / cg" |
|
936 ! |
|
937 |
|
938 asGrayFormOn:aDevice |
|
939 "get a gray device form. |
|
940 Redefined, since we can do it with simple translate, |
|
941 if the depth matches my depth." |
|
942 |
|
943 (aDevice visualType == #StaticGray) ifTrue:[ |
|
944 (aDevice depth == 8) ifTrue:[ |
|
945 ^ self asGray8FormOn:aDevice |
|
946 ]. |
|
947 ]. |
|
948 ^ super asGrayFormOn:aDevice |
|
949 |
|
950 "Created: 10.6.1996 / 18:51:19 / cg" |
|
951 "Modified: 10.6.1996 / 18:54:36 / cg" |
|
952 ! |
|
953 |
|
954 greyImageAsPseudoFormOn:aDevice |
|
955 "return a pseudoForm from the gray picture. The main work is |
|
956 in color reduction, when not all colors can be aquired." |
|
957 |
|
958 ^ self anyImageAsPseudoFormOn:aDevice |
|
959 |
|
960 "Modified: 19.10.1997 / 04:57:39 / cg" |
|
961 "Created: 19.10.1997 / 04:58:41 / cg" |
|
962 ! |
|
963 |
|
964 greyImageAsTrueColorFormOn:aDevice |
|
965 "return a true-color device-form for the grey-image receiver. |
|
966 Supports true color devices with depths: 8, 16, 24 and 32" |
|
967 |
|
968 |f| |
|
969 |
|
970 f := self anyImageAsTrueColorFormOn:aDevice. |
|
971 f notNil ifTrue:[^ f]. |
|
972 ^ super greyImageAsTrueColorFormOn:aDevice |
|
973 |
|
974 "Created: / 29.7.1998 / 00:19:46 / cg" |
|
975 ! |
|
976 |
|
977 paletteImageAsPseudoFormOn:aDevice |
|
978 "return a pseudoForm from the palette picture. The main work is |
|
979 in color reduction, when not all colors can be aquired." |
|
980 |
|
981 ^ self anyImageAsPseudoFormOn:aDevice |
|
982 |
|
983 "Modified: 19.10.1997 / 04:57:39 / cg" |
|
984 ! |
|
985 |
|
986 paletteImageAsTrueColorFormOn:aDevice |
|
987 "return a true-color device-form for the palette-image receiver. |
|
988 Supports true color devices with depths: 8, 16, 24 and 32" |
|
989 |
|
990 |f| |
|
991 |
|
992 f := self anyImageAsTrueColorFormOn:aDevice. |
|
993 f notNil ifTrue:[^ f]. |
|
994 ^ super paletteImageAsTrueColorFormOn:aDevice |
|
995 |
|
996 "Created: / 24.7.1998 / 01:20:46 / cg" |
|
997 "Modified: / 29.7.1998 / 00:19:27 / cg" |
|
998 ! |
|
999 |
|
1000 rgbImageAsTrueColorFormOn:aDevice |
|
1001 "return a true-color device-form for the rgb-image receiver. |
|
1002 Supports true color devices with depths: 8, 16, 24 and 32" |
|
1003 |
|
1004 |f| |
|
1005 |
|
1006 f := self anyImageAsTrueColorFormOn:aDevice. |
|
1007 f notNil ifTrue:[^ f]. |
|
1008 ^ super rgbImageAsTrueColorFormOn:aDevice |
|
1009 |
|
1010 "Created: / 29.7.1998 / 00:21:25 / cg" |
958 ! ! |
1011 ! ! |
959 |
1012 |
960 !Depth8Image methodsFor:'dither helpers'! |
1013 !Depth8Image methodsFor:'dither helpers'! |
961 |
1014 |
962 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth |
1015 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth |