home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume13 / imagemagic / part10 < prev    next >
Internet Message Format  |  1991-05-23  |  75KB

  1. Path: uunet!uunet!cs.utexas.edu!sun-barr!newstop!exodus!dupont.com!cristy
  2. From: cristy@dupont.com
  3. Newsgroups: comp.sources.x
  4. Subject: v13i026: ImageMagick - Graphics display programs, Part10/21
  5. Message-ID: <13940@exodus.Eng.Sun.COM>
  6. Date: 24 May 91 03:18:46 GMT
  7. References: <csx-13i017:imagemagic@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 2121
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: cristy@dupont.com
  13. Posting-number: Volume 13, Issue 26
  14. Archive-name: imagemagic/part10
  15.  
  16. #!/bin/sh
  17. # this is img.10 (part 10 of ImageMagick)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file ImageMagick/images/mandrill.miff.Z continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 10; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping ImageMagick/images/mandrill.miff.Z'
  35. else
  36. echo 'x - continuing file ImageMagick/images/mandrill.miff.Z'
  37. sed 's/^X//' << 'SHAR_EOF' >> '_shar_tmp_.tmp' &&
  38. M9+^/H7C3?(1ZOG=8D4<#PEKD9K-.0Y*_"B)CV&\0CE%SAP2^"FMZM7[(8OU8
  39. M+W/$CE1P2VO/5A81P(XQ%IM,\3/BAT4,H"YV9GQ<,)-G3DZ2[@_B*S%GUDNZ
  40. M"[DU_QL3*N5J4S]-9,U-)QH7%$8`[8"08Z=.6R>K@"!`JC71#:%4-2A&"NDJ
  41. M)0#6#Z<.&0`D`%A])`"E/"$76232!Y4&V0?M$YX%5`(;%"D`=0R[6"V//P++
  42. M>O4(XP.U!Z,[,(3>*6HDJPW;%TD"/`+E"$DB88.W,N`Y4P*Q'#$)Q!DR"40+
  43. M)!(I$2QP!P_"*=8,Y!9KB7YU8#P=161G03TY%@@*4)25'JT+"`HUA!`1A4WU
  44. M!J]-"#DZ4)$AMR+H7F]BTDSYBJ(@E`LCD3TH/2CV"!8`<V(F*84D?7T-"?\I
  45. MDUD=%9@"EP($"`(`A8][!0]?"89@2JAUBG8(&AT`"@`Q`.62&Y)S2KLU[@\Q
  46. M@(4"&I(R*9AL$Y)\1+4UFHG!;YX+X@511>(K&U6&)5]P59'B=2B2#FY,DJI7
  47. M^67Z=?!NGW&@<:%QG9#$3U]AU3WFCJIWM6;`<+APHWFGE-]"VG5Z`,=;JX2J
  48. M=\1/G)"FE(9P:WIJ5[-.W%309\=;7'.NB8N/,1:94'Y^547A9LH9CU:!7""3
  49. MAB5Q`'-*89)+*(9P()/\<?,K%PMD3L4`T0#`(D)5&@2V!N<=H"(#,WQV'F8_
  50. M`!:&S4VV!K]?CPN``!0J\(2I(=4-#0!3)]\00X[O%E@GV0?_$"@`MRQ7`B(7
  51. M<`NN#0\)EP+>%>@J&`H4%#^)GX$W)28"[A9$"UX"TP.I'QP`CF(<`-X2WPRR
  52. M#><6I0XF`B`GR@\^`LX;;GTL)_H.S$K#&>D"62A64]EZS14?-S`P?Y,L:TTO
  53. M[AZ$--<LWPP)./L;M8%7/=PT)S?M'`P<[1S2*'Q]QI$J/HT[#(4+:`D_HS2C
  54. M-(!A,B<#:%<"3@*'AG$G,PG@!ML2_!`F)PU_&S-$`!8RV5?0*Q\7&`!^CT)1
  55. M085V4+\?TA^9)'^)W`R-`F0`.A.YDSU6*V_\C#QL\ETC3']OXRO)9[<UZ1Z:
  56. MB3]8+"G;CY*4*)+*&1!M+"E.>KQ/,$AV<?%N(G0G4XUII0">45&!>D:F`*MX
  57. MD)!]D;X*KHFFE'=2N'"S3BISVG7Z=8=P\6[B*]QU:WJHD"MMLTZ&)=-\&77M
  58. MAR2!1P#<5,U6?43U<]1OT90<6#<4&CI!D:!JC)1!D0PJEPO:E-E1#RJ+`.HS
  59. M:65J98QA%BH@&ELGO@LM`(EDTAW(-.PZBT-!9:J3@(?5DNX73@+%#P$15P7V
  60. M"*",4@)/!=$#YQ'N%20%)0`8"H>4'@)3`@R0M(:[$)Q-3`NG!94?WCD=E=4#
  61. M\P:D!2X`(R48)DPL-P`2`AH_LA`C`"PO%D2C'E`+-HO,18%3O"KF.%&42R)X
  62. MCC&5Y!:^C"(;ISJ,'U@)4"+K'SH6FS-'-M(H*%Q')MP2K#H#A44W@&'70/TH
  63. M98^.#3Q0:0I:`D$7M`?O<-E7)B>=B`H)QQN0:Y,+,PDU,;P@[BL9+7Y^!Q(B
  64. M!,M'!$'T#T=1\4,8`*@U=R\2*3L8B%2#`&MDM04=7\]>2RA@6?HS1I$[%3(I
  65. MT33^DG\@Y"O5E`UN^6RC<-]"-6)1DN-UGD:-E223@)#8;X65=(NA<=)F5W*1
  66. ME=Q4XV8.;N-UWW=F5^EVY9/'6X>5^64L*=QUM7ZZDWE;@95[D15<=3>](DUR
  67. MU)2?6ZB0\EWB*VR6DD2F:(8EO2*:B9F5+"E$9N-@EVPE"%V2<B9"5A0JK"SF
  68. M'1L7&AFXE2T`?"](<*=.\VK`8A1&K$C;'I@"DPTR`"8%3@+.#>T7G8CJ$V,F
  69. M0`)+!?84(P!'"G@&T!!*!1`/7C'<`[P.&2;V&$`I-R6I'A$`#`"*(-<0^1M[
  70. M-=X-20#)6)D-O@\^`BT"+`+6"%$C8`85*"PG@P;V%,,9N0,D!18`/0`/'!$0
  71. M#XG3<F`\J'1FE&XU6X]8)1(0HSH'#S03*A+7%DA"4QF4!<Y+"C@J-S169'9@
  72. M/=F"&2LU5F6/'!K<5R@XPA_#3"4`2``19]\0-%`5%-\0(A?[D1DKN`P4%)@D
  73. MEP(&``4`A5.//5MEF`+X!T\X#TPI8XP"&015.&0`O#7J@665XF"'`H@/:S?N
  74. M#]L,A@+%6@:72$NGE<"(QI/I'GEI#5P793J6N'"J5[F##4&Y<`R-P(Y]1"%9
  75. M9X6:9!-VS0#C9N6.7',<DS]CPEJ':*MH%H*S3A:"PX[B"TEA:E<AD[U58);0
  76. M9QR3)U-#=#(Y]7/`CM-OWW3[DM=%\ET;:\:3U6\Z>,@`+AK7'H8E1&;N#SH3
  77. MCW6*/>Z2[AV5+I!C>07O';N5ZH$4*CTH,`"Z(E-]>@7CC/!&@6+I.C(`MQRJ
  78. MD^H."P#@$?4(.@IM+Z\-[A>S!T8"ZA4$5SP"-B@*`#4*C@S\#[('[ALY`-D'
  79. MA`8#`248V)63'Z,>0`7W`]('PQG5`QU%.A3/$Y8?YA3K&B*57@M8@\(#ESM?
  80. M.XB7S$KK&@J%/4[D%N4XZX5?6EIE]I7U!OP_3BBF`W9M-!-F+%Z4"`HP%5@)
  81. M$1"QD@\1R5BZ0.DYA#RF4^)P1X1J/!@HAC4="``9G7N)-@H)NPXL`MV0Q0_G
  82. M$L(?EP(+`,E'8V9^!04(+0"0`!$4_3*D6.4<TAT1*8P+FP6S+7$^M6&M898V
  83. M_I/"D\I^AP+'9[!HB`+R72PIBP*N6<J3/Y;^C+!H1I'#E#YKAU92`0U!M57)
  84. MDW=O=U+2DQ5<@VC8;^(KF0&'!+^4:WJ(E9-$JWB':&UYAW#8;RIUEI63`+AP
  85. MEI5Y6VMZ"&2HD#(YLTZ=1L]$`Y@4=#V79$X]ER"3VPQUD-P,BCV1E+H+<)9$
  86. M9HECV15K-[5Z:3``:<8[^Q#$+.`=]3,@0/A,P#1H?K,&]UU_8LM31#^X`U4P
  87. M>XW=`R46ZA5O"W^'"@`G`B4820LY"NT3-`KV%`D)"PD9`"AX(0H'$D(+JTE>
  88. M`KD"5@O?&I!KCQ^/-.^0+`"`8\H:_Q3V%!\%3@4*`L`2C1UC#"D*IP5.!?$/
  89. M3P6!#$D*P"AC-3(E*G#(&:@+]4MX=+B,60E!%9F3^XN>-H4^J`NE0X1'P$#$
  90. M<>T<F`<J-P<_H8=#!)XVCQ_"C%%W;"0!%3$:-'<'$K61EU,D!>4#49-9B#:4
  91. MNI?X#_D'`4L9``4`B%49`-H&"889`(``GXZC?3)+=@5SAUDX!AH5%\M@!U*.
  92. M`/=2`I>,`O4<09$&A\<A'3J<F&F5C``J1I)$FHG6`)R#H'$[%2ADV),UDK=P
  93. M7):21-)FLY2>6ZE7TWS8;Z60.FP;=<*4:Y:\F,1/7'.07A%TSW<G4Z<`NI,I
  94. MEZ-Q%'309\68AVC_DJI7M2(<D^22[)+R70*8-Q2+CZF5AB4Q*7)*)$R-`IQ#
  95. M!$;;F&]DO).7"\`B[GJ5-GR6C#9#`+\LFC:4`ML>_4JY!DYG>@7Z%X\+."@I
  96. M`)TMJC75#6,F)@7B.F\+EP*?+0(('Q?0*U0""PDD!>H#2PO.!YP>VQ<V-^@#
  97. M("=>`B**300.E4L$50NE#ADF.Q2-@OD"M0\4".8^G`Y"E,\#]`0-`OT!B1_H
  98. M`]4(\A?1*?@&T`BH+NJ%,##5#$HVD6SKA=B+D2$:!9Z7*9DY))H#F`<\)'L-
  99. M"SCM'MB+-1BXDF<X%&A#D*XC@(XI&!QG0`#YBB]E2051D#9^S0^F(*,T5P(6
  100. M&8-\*`CY!XN#&``1`-9!+@#4E+@&*P!S`%>0\P\VC5M"D)0D4G0%&P37("",
  101. M=9:,`C@4\EV+`M*4XBL!EZ`ND93,,_QV&&OB*V&2AG"GF,AG=)E1:K=PMFX;
  102. M:X]6:W(L;0YNO4CP;E]KO2*X<#)T4P%K<XV5EY5K>A:"P78REWD`<DISEKU5
  103. MTY>.E3<4PY0$4_(KY6:EE`F8*Q>@+@>8U90R.8T"S&'&DV@PI9A$9M4T04H#
  104. M0/@Z&TI\-TLH>"^-`/0/Z!V$`-]SK4*5-DMDN6QN)B($*`"$2=1>-2AB9M4-
  105. M;PNN(1(4MPSJ%2D%^YB#-N<8S0<%`-D1])0[,E<%.IB:!N@#/P0E`.<(7@G-
  106. M$34"U'02.'<,<R$9*)\.Z`,7"BX`VA)4)<H/Q!+GE=(#5@NF#?P/BPL'!0,!
  107. MSR?$&54#BBR!5L0H?Y,=-QL1^Q@#<4($=@X<D=E`TS_X!JYIJ`N8!R<WR6C`
  108. M0&(A)B^SDGYC[1S!:K<R*P`Y)'5"6F7O<.0Y%)4K2A<3"@G_*3\*=9<0">V&
  109. M)BF9CB\`XCKV%(\+YY;VAOP'V6"5`J%]!0CK1H0`&P"$`,E7SR`?!/,'YT&/
  110. M3B1,LDR:E88E'QO]6`>7N3614X8EM54]5E"+QR&#<IU/,YJLF-64<);_C#^7
  111. MC94H9,"(,'0CD[-.KFBED/`E_Y)#EO&7R&)KEJ-W_)?RD]&3%Y/UE]Q4DP`N
  112. M<Y:5E977E]!G#4&<0\T``9>8F=>7AB6EF)^9`TTSFO=2GE'8(-N8BY1?,&>:
  113. M&@1H5;14FYG@*]4TK3S"(;29%106AN9J^Q"_?-L>%!1OCVQC1@!'E0P`)P`7
  114. M$R46MQRY`[P,MQS9$24`89<&&T`"*04!".`#G@59!2$7]Y0>`ND(;H$6"N0#
  115. M#0+H`Q8`1`!G"L(#H(Q#!%`%`P$+,:$@CAU!?CT"[Q8V`GZ71`L%"?,6IP71
  116. M`_46I(%("WJ7RDM!(QXDQ"B94K,+NFI?;/`K]0Z:C1L1_Y6F`SI`-)F]C*LR
  117. MQRBP$#E/:V(T5O4&7'RW,M&`P$`\D`N6L8T9,>T1PW0<%9.,V%=D"Q<%6T],
  118. M)1P5#(RX!K$#KB$Z48\+SX<:`!\`:G#W"&(`OPPO`&4`&`"#`(@/\AS2'R=2
  119. MD%7]46Y)TXTW%`&79%5(2\.3:IJW-=YI@5QWBCL5V)1$FI)$!5,4=&&:!5GE
  120. MDA=ED%Y-DFN6^642&"U,9UF]3PU!8VLVC/>7CI709R&3S0#7;]!GF97<=5V6
  121. M:E>,`-QU9YEPEH=H<I709V&2XBO]6`&7*YMTEC&;F)FR(M.8QBQY6\@`D0+M
  122. M'695S0!U/D%*!$!BE?)=E39_('8^A@#_4@X:2SC,D.J4@%4U*#TH07\%$AD5
  123. M;Y0[!0`1YQB+"^(Z[!3H*@((PIF+FGN-,C$-`',G1`JU#Q0`[@/5#S8^00+Z
  124. M"!``G@71$+0'[Q-""]@77@*2(#(%S)7E`^\3P#IT8X\?BXWE)[@S[!H6"J1%
  125. M9DOF%"9)S@G:,EP'/7W]"%]LCAU$`2H2FAIX"HT\CQT)"A1H>(XWD%D)P3D8
  126. M$==P8#7_F>@GL063!24O?`UGF#D6+)#W47%]M#K8/V&83B46,=T2O1(J`"(`
  127. MBPP.*!)IQANO:L(?)H3^2O%2M0^!24%_8F9C1)`]D``*`$%B,2P8`"H`R%EW
  128. M#@=[^P?2'PERO4&1`B1,TYA>9[,MEC:7E,`B,YKB#>(KB6-O"I$`<IEPE=.8
  129. MUY?B8,.3)4R?F:!Q-Q05=-]F=VK?F].77F>Y5)"0J&C!F+R8H'&6E7R0RGZS
  130. M3BM&'YO<=>(KTY?!D[U5I9@CFY,`X9N:E2M&-Q0$4V:9.!1$9@)2,YK.6-N8
  131. M.!0-&:J9S#-X+Y,`U33^43(Y04J&`CH3%QO0+($E%QCE:D,Q<R\<>LYT,PG[
  132. M$$%__DH?FKB7S`?5#;<<&`KA`\`@T@T`$>4<&``$"+4#@078!]$0B0L.*"X`
  133. M)`#2E<X#1G4Z"H8,*P`[`(X,A`:Z!SD%%`"?!ZL-<R'/`\0<]7E*!#\%?0Q9
  134. M-JH;\1<$`7<$KQS1$!<`GP6T.<,#PP,+`*L09B$N)-@$&!%H-:L+G1)+(O4&
  135. M;DAW6N(X%WDN),LHF`=@-981E1&P"_\W@I.-@GEMH72$-*H%E6HP,'"(S(#1
  136. M$>@1BPRK.]R:\@/"'WR"^A1PE">$FU4<@_8(_4IG"K<&7DJ,68\`%@"9"KLE
  137. M#0`M`%X`"@"R+:-LL(@D4B-2_TLB7@\JBP+]C&B:RW-OFA*8L36(`@*<DI3H
  138. M3?R,9IJ&)=L,+IO,`/N;:##5E*N8(TSC8,EG,CF=3Z"/,BGTFRIS37(!;`]N
  139. MVIO3E_N;Q)2X<,*4:I8NE\:8^V0^'[=(W'5;F@13+)M>FI29,YK]FRN;V5'3
  140. MF)(`*9LD3#]6DEK7;V@PUTT..3N;O4%C964`*Q>L85LXE"Y`,11&@27T5GD%
  141. MZX94B.<J:2]CC3THBBX4%.<2S`<%`"@`M0.3#<J9P"`B*>H5'P"!!;^7!@@;
  142. M%/8410(J`%M/1@KG&-8-QR!NEQ(`V@/K&K00V`.H'!D`1`L'"<,#M0\@``$!
  143. M64\1E1"9S@D4G=,:(I7S%H(PX!?I%M<3R@^7`J:6LAP]BT($DY>]FNN%$1#T
  144. M'54QICHV>/)0?F-%-J8Z+B3D%=0,Z!^P"U@TK"XPG6XU*'!+=]$14H*;=#V5
  145. M\Q/20%$%BVR4:T`"3"5"/KD"2`1`%R>$KI'F"#,)]@,&`/00-(L/,R82<0!_
  146. M!?"6(18A`,H`C@!B`*J1"1HJ:-U,O4$`FW(WD@(TF@-`H9R["^R2C`+3C6!9
  147. MFHF5B7*5V91`D61@TYP-;D&189)'EV)A/58&`SJ;>V!BFD1F29)&EE,!H(]@
  148. MFBISM7X4=.:;)9OUFR6;CH_7;V)S<TK09^T=UYC@F[=P+C)J5]YI:)H]5L8`
  149. M9E4#33<G*QDAFY``E@"PG/=7JC38(')#:%477^-@W`[?DA,J90`+DIAMGR+F
  150. M'8$E;Y1"93$`B0O1'Q44S3O;'FZ/5P4:`A,`)YS=`Y,-"`#B.@L`PIG/#5>;
  151. M#0`"`,*-`@`3,D@%V1&_#XHVB9+N%D4"RP;/,AX"]1/**;0S("<O!3D*U@@@
  152. M!4*8_W#V$]`1%S_1`^43(@#GE5,"TA!^!>8()P45`"HF[1+#`_,6$@(Y"!@1
  153. MY3@')5J)UPQ"!-EZ$A#27YH#JPL8>2:5V7HTF2H2S9J]5^P_'`7,,;\I.22F
  154. M`CH45(GW4348"P_9$B8Z8Y-JAR@:Y7%)!1&63"4E&\8.MHOID(HF[AN9)1,4
  155. MR4=@`+N;ZD:E5,-+`P#B'+(MQ"SRAO@'&P3534QP^YMU/CV;\P?\6$=+[)*@
  156. M:HT"&I)$9FV5_(P]GL`B<TKN#]R;N37N#RYS:Y90"<\`UV\_EF.:/9<"F/EN
  157. MY9)C<R-,/&.7E5*:.YLTEV4`8I:1F;R<8IJ8G<"4PYR3`-2<8YJ':/N7PYS7
  158. MEZ><SIQGFCJ;-EV]8"EYEC8-&9``8E69G3<GD`)!2MU,W4:+`L0L;#"7F&``
  159. M8424`D0X&$P?0.V<'1D4%..,08XI`#(`"X8U;[:+]0A2!BXO!QL'&QD`"`!A
  160. MFQH"LBR)GER;@@6C`I4->XVP#2F)[0,F!=(0!@`?`"4*B`;?*2$*Y)!>`@0Q
  161. M55.J(J8-GP<V!0<)IASQ%JL'>`8M,.84P@/I""\+[AL@GN$#S@?RG0H`#@'`
  162. MGL&>PIZM`L2>PYX-`0P!QI[)GLJ>RY[,GLV>SI[/GLF>R)[0GM.>U)[5GM:>
  163. MQI[2GM>>QY[;GL&>#`'>G@``X&<.`0X=R)[?GL.>V9[+GN>>RI[GGNF>VI[M
  164. -GL*>[)[NGO&>\I[4G@'>
  165. `
  166. end
  167. SHAR_EOF
  168. echo 'File ImageMagick/images/mandrill.miff.Z is complete' &&
  169. echo 'uudecoding file ImageMagick/images/mandrill.miff.Z' &&
  170. uudecode < _shar_tmp_.tmp && rm -f _shar_tmp_.tmp &&
  171. chmod 0700 ImageMagick/images/mandrill.miff.Z ||
  172. echo 'restore of ImageMagick/images/mandrill.miff.Z failed'
  173. Wc_c="`wc -c < 'ImageMagick/images/mandrill.miff.Z'`"
  174. test 204043 -eq "$Wc_c" ||
  175.     echo 'ImageMagick/images/mandrill.miff.Z: original size 204043, current size' "$Wc_c"
  176. rm -f _shar_wnt_.tmp
  177. fi
  178. # ============= ImageMagick/import.c ==============
  179. if test -f 'ImageMagick/import.c' -a X"$1" != X"-c"; then
  180.     echo 'x - skipping ImageMagick/import.c (File already exists)'
  181.     rm -f _shar_wnt_.tmp
  182. else
  183. > _shar_wnt_.tmp
  184. echo 'x - extracting ImageMagick/import.c (Text)'
  185. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/import.c' &&
  186. /*
  187. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  188. %                                                                             %
  189. %                                                                             %
  190. %                                                                             %
  191. %                 IIIII  M   M  PPPP    OOO   RRRR    TTTTT                   %
  192. %                   I    MM MM  P   P  O   O  R   R     T                     %
  193. %                   I    M M M  PPPP   O   O  RRRR      T                     %
  194. %                   I    M   M  P      O   O  R R       T                     %
  195. %                 IIIII  M   M  P       OOO   R  R      T                     %
  196. %                                                                             %
  197. %                                                                             %
  198. %             Import X11 image to a machine independent format.               %
  199. %                                                                             %
  200. %                                                                             %
  201. %                                                                             %
  202. %                           Software Design                                   %
  203. %                             John Cristy                                     %
  204. %                            January  1991                                    %
  205. %                                                                             %
  206. %                                                                             %
  207. %  Copyright 1991 E. I. Dupont de Nemours & Company                           %
  208. %                                                                             %
  209. %  Permission to use, copy, modify, distribute, and sell this software and    %
  210. %  its documentation for any purpose is hereby granted without fee,           %
  211. %  provided that the above Copyright notice appear in all copies and that     %
  212. %  both that Copyright notice and this permission notice appear in            %
  213. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  214. %  & Company not be used in advertising or publicity pertaining to            %
  215. %  distribution of the software without specific, written prior               %
  216. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  217. %  about the suitability of this software for any purpose.  It is provided    %
  218. %  "as is" without express or implied warranty.                               %
  219. %                                                                             %
  220. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  221. %  to this software, including all implied warranties of merchantability      %
  222. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  223. %  liable for any special, indirect or consequential damages or any           %
  224. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  225. %  in an action of contract, negligence or other tortious action, arising     %
  226. %  out of or in connection with the use or performance of this software.      %
  227. %                                                                             %
  228. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  229. %
  230. %  Import is an X Window System window dumping utility.  Import allows X
  231. %  users to store window images in a specially formatted dump file.  This
  232. %  file can then be read by the Display utility for redisplay, printing,
  233. %  editing, formatting, archiving, image processing, etc.  The target
  234. %  window can be specified by id or name or be selected by clicking the
  235. %  mouse in the desired window.  The keyboard bell is rung once at the
  236. %  beginning of the dump and twice when the dump is completed.
  237. %
  238. %  The import program command syntax is:
  239. %
  240. %  Usage: import [options ...] file
  241. %
  242. %  Where options include:
  243. %    -border          include image borders in the output image
  244. %    -display server  X server to contact
  245. %    -frame           include window manager frame
  246. %    -id number       select window with this resource id
  247. %    -monochrome      transform image to black and white
  248. %    -name name       select window with this WM_NAME property
  249. %    -root            select root window
  250. %    -scene           image scene number
  251. %    -screen          select image from root window
  252. %
  253. %  Change '-' to '+' in any option above to reverse its effect.
  254. %  For example, +frame means do not window manager frame.
  255. %
  256. %  Specify 'file' as '-' for standard input or output.
  257. %
  258. %
  259. */
  260. X
  261. /*
  262. X  Include declarations.
  263. */
  264. #include "display.h"
  265. #include "image.h"
  266. #include "X.h"
  267. X
  268. /*
  269. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  270. %                                                                             %
  271. %                                                                             %
  272. %                                                                             %
  273. %   E r r o r                                                                 %
  274. %                                                                             %
  275. %                                                                             %
  276. %                                                                             %
  277. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  278. %
  279. %  Function Error displays an error message and then terminates the program.
  280. %
  281. %  The format of the Error routine is: 
  282. %
  283. %      Error(message,qualifier)
  284. %
  285. %  A description of each parameter follows: 
  286. %
  287. %    o message: Specifies the message to display before terminating the
  288. %      program.
  289. %
  290. %    o qualifier: Specifies any qualifier to the message.
  291. %
  292. %
  293. */
  294. void Error(message,qualifier)
  295. char
  296. X  *message,
  297. X  *qualifier;
  298. {
  299. X  (void) fprintf(stderr,"%s: %s",application_name,message);
  300. X  if (qualifier != (char *) NULL)
  301. X    (void) fprintf(stderr," (%s)",qualifier);
  302. X  (void) fprintf(stderr,".\n");
  303. X  exit(1);
  304. }
  305. X
  306. /*
  307. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  308. %                                                                             %
  309. %                                                                             %
  310. %                                                                             %
  311. %   U s a g e                                                                 %
  312. %                                                                             %
  313. %                                                                             %
  314. %                                                                             %
  315. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  316. %
  317. %  Procedure Usage displays the program usage;
  318. %
  319. %  The format of the Usage routine is:
  320. %
  321. %      Usage(message)
  322. %
  323. %  A description of each parameter follows:
  324. %
  325. %    message:Specifies a specific message to display to the user.
  326. %
  327. */
  328. static void Usage(message)
  329. char
  330. X  *message;
  331. {
  332. X  char
  333. X    **p;
  334. X
  335. X  static char
  336. X    *options[]=
  337. X    {
  338. X      "-border          include image borders in the output image",
  339. X      "-display server  X server to contact",
  340. X      "-frame           include window manager frame",
  341. X      "-id number       select window with this resource id",
  342. X      "-monochrome      transform image to black and white",
  343. X      "-name name       select window with this WM_NAME property",
  344. X      "-root            select root window",
  345. X      "-scene           image scene number",
  346. X      "-screen          select image from root window",
  347. X      (char *) NULL
  348. X    };
  349. X  if (message != (char *) NULL)
  350. X    (void) fprintf(stderr,"Can't continue, %s.\n\n",message);
  351. X  (void) fprintf(stderr,"Usage: %s [options ...] file\n",application_name);
  352. X  (void) fprintf(stderr,"\nWhere options include:\n");
  353. X  for (p=options; *p != (char *) NULL; p++)
  354. X    (void) fprintf(stderr,"  %s\n",*p);
  355. X  (void) fprintf(stderr,
  356. X    "\nChange '-' to '+' in any option above to reverse its effect.\n");
  357. X  (void) fprintf(stderr,
  358. X    "For example, +frame means do not include window manager frame.\n");
  359. X  (void) fprintf(stderr,"\nSpecify 'file' as '-' for standard output.\n");
  360. X  exit(1);
  361. }
  362. X
  363. /*
  364. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  365. %                                                                             %
  366. %                                                                             %
  367. %                                                                             %
  368. %    M a i n                                                                  %
  369. %                                                                             %
  370. %                                                                             %
  371. %                                                                             %
  372. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  373. %
  374. %
  375. */
  376. int main(argc,argv)
  377. int
  378. X  argc;
  379. X
  380. char
  381. X  *argv[];
  382. {
  383. X  char
  384. X    *filename,
  385. X    *option,
  386. X    *server_name,
  387. X    *user_default;
  388. X
  389. X  Display
  390. X    *display;
  391. X
  392. X  Image
  393. X    *image;
  394. X
  395. X  int
  396. X    i;
  397. X
  398. X  unsigned int
  399. X    borders,
  400. X    frame,
  401. X    j,
  402. X    monochrome,
  403. X    scene,
  404. X    screen;
  405. X
  406. X  Window
  407. X    client_window,
  408. X    root_window,
  409. X    target_window;
  410. X
  411. X  /*
  412. X    Display usage profile if there are no command line arguments.
  413. X  */
  414. X  application_name=(*argv);
  415. X  if (argc < 2)
  416. X    Usage((char *) NULL);
  417. X  /*
  418. X    Connect to X server.
  419. X  */
  420. X  server_name=(char *) NULL;
  421. X  for (i=1; i < argc; i++)
  422. X  {
  423. X    /*
  424. X      Check command line for server name.
  425. X    */
  426. X    option=argv[i];
  427. X    if ((strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  428. X      if (strncmp("dis",option+1,3) == 0)
  429. X        {
  430. X          /*
  431. X            User specified server name.
  432. X          */
  433. X          i++;
  434. X          if (i == argc)
  435. X            Usage("missing server name on -display");
  436. X          server_name=argv[i];
  437. X          break;
  438. X        }
  439. X  }
  440. X  display=XOpenDisplay(server_name);
  441. X  if (display == (Display *) NULL)
  442. X    Error("unable to connect to X server",XDisplayName(server_name));
  443. X  root_window=XRootWindow(display,XDefaultScreen(display));
  444. X  /*
  445. X    Get X defaults.
  446. X  */
  447. X  user_default=XGetDefault(display,application_name,"borders");
  448. X  borders=IsTrue(user_default);
  449. X  user_default=XGetDefault(display,application_name,"frame");
  450. X  frame=IsTrue(user_default);
  451. X  user_default=XGetDefault(display,application_name,"monochrome");
  452. X  monochrome=IsTrue(user_default);
  453. X  user_default=XGetDefault(display,application_name,"scene");
  454. X  scene=(user_default == (char *) NULL) ? 0 : atoi(user_default);
  455. X  user_default=XGetDefault(display,application_name,"screen");
  456. X  screen=IsTrue(user_default);
  457. X  /*
  458. X    Check command syntax.
  459. X  */
  460. X  filename=(char *) NULL;
  461. X  target_window=(Window) NULL;
  462. X  for (i=1; i < argc; i++)
  463. X  {
  464. X    option=argv[i];
  465. X    if ((strlen(option) < 2) || ((*option != '-') && (*option != '+')))
  466. X      filename=argv[i];
  467. X    else
  468. X      switch(*(option+1))
  469. X      {
  470. X        case 'b':
  471. X        {
  472. X          borders=(*option == '-');
  473. X          break;
  474. X        }
  475. X        case 'd':
  476. X        {
  477. X          /*
  478. X            User specified server name.
  479. X          */
  480. X          i++;
  481. X          if (i == argc)
  482. X            Usage("missing server name on -display");
  483. X          server_name=argv[i];
  484. X          break;
  485. X        }
  486. X        case 'h':
  487. X        {
  488. X          Usage((char *) NULL);
  489. X          break;
  490. X        }
  491. X        case 'f':
  492. X        {
  493. X          frame=(*option == '-');
  494. X          break;
  495. X        }
  496. X        case 'i':
  497. X        {
  498. X          i++;
  499. X          if (i == argc)
  500. X            Usage("missing id on -id");
  501. X          option=argv[i];
  502. X          target_window=(Window) strtol(option,(char **) NULL,0);
  503. X          break;
  504. X        }
  505. X        case 'm':
  506. X        {
  507. X          monochrome=(*option == '-');
  508. X          break;
  509. X        }
  510. X        case 'n':
  511. X        {
  512. X          i++;
  513. X          if (i == argc)
  514. X            Usage("missing name on -name");
  515. X          option=argv[i]; 
  516. X          target_window=XWindowByName(display,root_window,option);
  517. X          if (target_window == (Window) NULL)
  518. X            (void) fprintf(stderr,"No window with name %s exists!\n",option);
  519. X          break;
  520. X        }
  521. X        case 'r':
  522. X        {
  523. X          target_window=root_window;
  524. X          break;
  525. X        }
  526. X        case 's': 
  527. X        {
  528. X          if (strncmp("scene",option+1,4) == 0)
  529. X            {
  530. X              i++;
  531. X              if (i == argc)
  532. X                Usage("missing scene on -scene");
  533. X              scene=atoi(argv[i]);
  534. X            }
  535. X          else
  536. X            if (strncmp("screen",option+1,4) == 0)
  537. X              screen=(*option == '-');
  538. X            else
  539. X              Usage((char *) NULL);
  540. X          break;
  541. X        }
  542. X        default:
  543. X          Usage((char *) NULL);
  544. X      }
  545. X  }
  546. X  if (filename == (char *) NULL)
  547. X    Usage("missing an image file name");
  548. X  /*
  549. X    If the window is not specified, let the user choose one with the mouse.
  550. X  */
  551. X  if (target_window == (Window) NULL)
  552. X    target_window=XSelectWindow(display,root_window);
  553. X  client_window=target_window;
  554. X  if (target_window != root_window)
  555. X    if (XGetGeometry(display,target_window,&root_window,&i,&i,&j,&j,&j,&j) != 0)
  556. X      {
  557. X        /*
  558. X          Get client window.
  559. X        */
  560. X        client_window=XClientWindow(display,target_window);
  561. X        if (!frame)
  562. X          target_window=client_window;
  563. X      }
  564. X  image=XReadImage(display,root_window,target_window,client_window,screen,
  565. X    borders);
  566. X  if (image == (Image *) NULL)
  567. X    exit(1);
  568. X  image->scene=scene;
  569. X  if (monochrome)
  570. X    {
  571. X      register unsigned int
  572. X        bit;
  573. X
  574. X      /*
  575. X        Convert image to monochrome PseudoColor class.
  576. X      */
  577. X      (void) QuantizeImage(image,2,0,False,True);
  578. X      bit=Intensity(image->colormap[0]) > Intensity(image->colormap[1]);
  579. X      image->colormap[bit].red=0;
  580. X      image->colormap[bit].green=0;
  581. X      image->colormap[bit].blue=0;
  582. X      image->colormap[!bit].red=255;
  583. X      image->colormap[!bit].green=255;
  584. X      image->colormap[!bit].blue=255;
  585. X    }
  586. X  (void) strcpy(image->filename,filename);
  587. X  (void) fprintf(stderr,"[%d] %s %dx%d\n",image->scene,image->filename,
  588. X    image->columns,image->rows);
  589. X  (void) WriteImage(image);
  590. X  DestroyImage(image);
  591. X  return(False);
  592. }
  593. SHAR_EOF
  594. chmod 0755 ImageMagick/import.c ||
  595. echo 'restore of ImageMagick/import.c failed'
  596. Wc_c="`wc -c < 'ImageMagick/import.c'`"
  597. test 14198 -eq "$Wc_c" ||
  598.     echo 'ImageMagick/import.c: original size 14198, current size' "$Wc_c"
  599. rm -f _shar_wnt_.tmp
  600. fi
  601. # ============= ImageMagick/import.man ==============
  602. if test -f 'ImageMagick/import.man' -a X"$1" != X"-c"; then
  603.     echo 'x - skipping ImageMagick/import.man (File already exists)'
  604.     rm -f _shar_wnt_.tmp
  605. else
  606. > _shar_wnt_.tmp
  607. echo 'x - extracting ImageMagick/import.man (Text)'
  608. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/import.man' &&
  609. .ad l
  610. .nh
  611. .TH IMPORT 1 "1 January 1991" "X Version 11"
  612. .SH NAME
  613. import - dump an image of an X window as MIFF
  614. .SH SYNOPSIS
  615. .B "import"
  616. [ \fIoptions\fP ... ] \fIfile\fP
  617. .SH DESCRIPTION
  618. .PP
  619. .I Import
  620. is an X Window System window dumping utility.
  621. .I Import
  622. allows X users to store window images in a specially formatted dump
  623. file.  This file can then be read by the \fIDisplay\fP utility for
  624. redisplay, printing, editing, formatting, archiving, image processing, etc.
  625. The target window can be specified by id or name or be selected by clicking 
  626. the mouse in the desired window.  The keyboard bell is rung once at the 
  627. beginning of the dump and twice when the dump is completed.
  628. .SH EXAMPLES
  629. .PP
  630. To select a X window and save it in the MIFF format to a file on disk
  631. titled window.ps, use:
  632. .PP
  633. X     import window.ps
  634. .PP
  635. To save the entire X server screen in the MIFF format to a file on disk
  636. titled root.ps, use:
  637. .PP
  638. X     import -root root.ps
  639. .SH OPTIONS
  640. \fIImport\fP options can appear on the command line or in your X resources
  641. file (see X(1)).  Options on the command line supercede values specified
  642. in your X resources file.
  643. .TP 5
  644. .B "-border"
  645. include image borders in the output image.
  646. .TP 5
  647. .B "-display \fIhost:display[.screen]\fP"
  648. specifies the X server to contact; see \fBX(1)\fP.
  649. .TP 5
  650. .B "-frame"
  651. include window manager frame.
  652. .TP 5
  653. .B "-id \fIvalue\fP"
  654. select window with this resource id.
  655. X
  656. See \fBxwininfo(1)\fP for one way of listing window resource id's.
  657. .TP 5
  658. .B "-monochrome"
  659. transform image to black and white.
  660. .TP 5
  661. .B "-name \fIname\fP"
  662. select window with this WM_NAME property.
  663. X
  664. See \fBxprop(1)\fP for one way of listing window property's.
  665. .TP 5
  666. .B "-root"
  667. select root window.
  668. .TP 5
  669. .B "-scene"
  670. image scene number.
  671. .TP 5
  672. .B "-screen"
  673. This option indicates that the GetImage request used to obtain the image
  674. should be done on the root window, rather than directly on the specified
  675. window.  In this way, you can obtain pieces of other windows that overlap
  676. the specified window, and more importantly, you can capture menus or other
  677. popups that are independent windows but appear over the specified window.
  678. .PP
  679. Change \fI-\fP to \fI+\fP in any option above to reverse its effect.  For
  680. example \fB+frame\fP means do include window manager frame.
  681. .PP
  682. Specify \fIfile\fP as \fI-\fP for standard input or output.
  683. .PP
  684. .SH ENVIRONMENT
  685. .PP
  686. .TP 5
  687. .B DISPLAY
  688. To get the default host, display number, and screen.
  689. .SH SEE ALSO
  690. XX(1), display(1), XtoPS(1)
  691. .SH COPYRIGHT
  692. Copyright 1991 E. I. Dupont de Nemours & Company                           
  693. .PP                                                                           
  694. Permission to use, copy, modify, distribute, and sell this software and    
  695. its documentation for any purpose is hereby granted without fee,           
  696. provided that the above copyright notice appear in all copies and that     
  697. both that copyright notice and this permission notice appear in            
  698. supporting documentation, and that the name of E. I. Dupont de Nemours     
  699. & Company not be used in advertising or publicity pertaining to            
  700. distribution of the software without specific, written prior               
  701. permission.  E. I. Dupont de Nemours & Company makes no representations    
  702. about the suitability of this software for any purpose.  It is provided    
  703. "as is" without express or implied warranty.                               
  704. .PP
  705. E. I. Dupont de Nemours & Company disclaims all warranties with regard     
  706. to this software, including all implied warranties of merchantability      
  707. and fitness, in no event shall E. I. Dupont de Nemours & Company be        
  708. liable for any special, indirect or consequential damages or any           
  709. damages whatsoever resulting from loss of use, data or profits, whether    
  710. in an action of contract, negligence or other tortious action, arising     
  711. out of or in connection with the use or performance of this software.      
  712. .SH AUTHORS
  713. John Cristy, E.I. DuPont De Nemours & Company Incorporated
  714. X
  715. SHAR_EOF
  716. chmod 0755 ImageMagick/import.man ||
  717. echo 'restore of ImageMagick/import.man failed'
  718. Wc_c="`wc -c < 'ImageMagick/import.man'`"
  719. test 3992 -eq "$Wc_c" ||
  720.     echo 'ImageMagick/import.man: original size 3992, current size' "$Wc_c"
  721. rm -f _shar_wnt_.tmp
  722. fi
  723. # ============= ImageMagick/kolb.c ==============
  724. if test -f 'ImageMagick/kolb.c' -a X"$1" != X"-c"; then
  725.     echo 'x - skipping ImageMagick/kolb.c (File already exists)'
  726.     rm -f _shar_wnt_.tmp
  727. else
  728. > _shar_wnt_.tmp
  729. echo 'x - extracting ImageMagick/kolb.c (Text)'
  730. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/kolb.c' &&
  731. /*
  732. X  March 1990
  733. X
  734. X  This is essentially Craig Kolb's color reduction code.  I made a few 
  735. X  changes mostly in routine colorquant (which now called Quantize) to
  736. X  support my MIFF image format.  This version also allows 4096 colors
  737. X  instead of 256.
  738. X
  739. X  cristy@dupont.com
  740. */
  741. X
  742. static void QuantHistogram();
  743. static void BoxStats();
  744. static void UpdateFrequencies();
  745. static void ComputeRGBMap();
  746. static void SetRGBmap();
  747. static void find_colors();
  748. static int  CutBoxes();
  749. static int  CutBox();
  750. static int  GreatestVariance();
  751. static int  FindCutpoint();
  752. static int  getneighbors();
  753. static int  makenearest();
  754. X
  755. /*
  756. X * This software is copyrighted as noted below.  It may be freely copied,
  757. X * modified, and redistributed, provided that the copyright notice is 
  758. X * preserved on all copies.
  759. X * 
  760. X * There is no warranty or other guarantee of fitness for this software,
  761. X * it is provided solely "as is".  Bug reports or fixes may be sent
  762. X * to the author, who may or may not act on them as he desires.
  763. X *
  764. X * You may not include this software in a program or other software product
  765. X * without supplying the source, or without informing the end-user that the 
  766. X * source is available for no extra charge.
  767. X *
  768. X * If you modify this software, you should include a notice giving the
  769. X * name of the person performing the modification, the date of modification,
  770. X * and the reason for such modification.
  771. X */
  772. /*
  773. X * colorquant.c
  774. X *
  775. X * Perform variance-based color quantization on a "full color" image.
  776. X * Author:  Craig Kolb
  777. X *    Department of Mathematics
  778. X *    Yale University
  779. X *    kolb@yale.edu
  780. X * Date:  Tue Aug 22 1989
  781. X * Copyright (C) 1989 Craig E. Kolb
  782. X * $Id: colorquant.c,v 1.3 89/12/03 18:27:16 craig Exp $
  783. X *
  784. X * $Log:  colorquant.c,v $
  785. X * Revision 1.3  89/12/03  18:27:16  craig
  786. X * Removed bogus integer casts in distance calculation in makenearest().
  787. X * 
  788. X * Revision 1.2  89/12/03  18:13:12  craig
  789. X * FindCutpoint now returns FALSE if the given box cannot be cut.  This
  790. X * to avoid overflow problems in CutBox.
  791. X * "whichbox" in GreatestVariance() is now initialized to 0.
  792. X * 
  793. X */
  794. #include "display.h"
  795. #include "image.h"
  796. #ifndef HUGE
  797. #define HUGE  HUGE_VAL
  798. #endif
  799. /*
  800. X * Maximum number of colormap entries.  To make larger than 2^8, the rgbmap
  801. X * type will have to be changed from unsigned chars to something larger.
  802. X */
  803. #define MAXCOLORS    255
  804. /*
  805. X * Value corresponding to full intensity in colormap.  The values placed
  806. X * in the colormap are scaled to be between zero and this number.  Note
  807. X * that anything larger than 255 is going to lead to problems, as the
  808. X * colormap is declared as an unsigned char.
  809. X */
  810. #define FULLINTENSITY    255
  811. #define MAX(x,y)  ((x) > (y) ? (x) : (y))
  812. X
  813. /*
  814. X * Readability constants.
  815. X */
  816. #define REDI    0  
  817. #define GREENI    1
  818. #define BLUEI    2  
  819. #define TRUE    1
  820. #define FALSE    0
  821. X
  822. typedef struct {
  823. X  double    
  824. X    weightedvar;  /* weighted variance */
  825. X
  826. X  float
  827. X    mean[3];      /* centroid */
  828. X
  829. X  unsigned long   
  830. X    weight,         /* # of pixels in box */
  831. X    freq[3][MAXCOLORS];  /* Projected frequencies */
  832. X
  833. X  int     
  834. X    low[3], 
  835. X    high[3];        /* Box extent */
  836. } Box;
  837. X
  838. unsigned long    
  839. X  *Histogram,   /* image histogram */
  840. X  NPixels;      /* total # of pixels */
  841. X
  842. unsigned int   
  843. X  Colors,      /* Maximum colormap entries */
  844. X  Bits,        /* # significant input bits */
  845. X  ColormaxI;   /* # of colors, 2^Bits */
  846. X
  847. /*
  848. X * Perform variance-based color quantization on a 24-bit image.
  849. X *
  850. X * Input consists of:
  851. X *  red, green, blue  Arrays of red, green and blue pixel
  852. X *        intensities stored as unsigned characters.
  853. X *        The color of the ith pixel is given
  854. X *        by red[i] green[i] and blue[i].  0 indicates
  855. X *        zero intensity, 255 full intensity.
  856. X *  pixels      The length of the red, green and blue arrays
  857. X *        in bytes, stored as an unsigned long int.
  858. X *  colormap    Points to the colormap.  The colormap
  859. X *        consists of red, green and blue arrays.
  860. X *        The red/green/blue values of the ith
  861. X *        colormap entry are given respectively by
  862. X *        colormap[0][i], colormap[1][i] and
  863. X *        colormap[2][i].  Each entry is an unsigned char.
  864. X *  colors      The number of colormap entries, stored
  865. X *        as an integer.  
  866. X *  bits      The number of significant bits in each entry
  867. X *        of the red, green and blue arrays. An integer.
  868. X *  rgbmap      An array of unsigned chars of size (2^bits)^3.
  869. X *        This array is used to map from pixels to
  870. X *        colormap entries.  The 'prequantized' red,
  871. X *        green and blue components of a pixel
  872. X *        are used as an index into rgbmap to retrieve
  873. X *        the index which should be used into the colormap
  874. X *        to represent the pixel.  In short:
  875. X *        index = rgbmap[(((r << bits) | g) << bits) | b];
  876. X *   fast      If non-zero, the rgbmap will be constructed
  877. X *        quickly.  If zero, the rgbmap will be built
  878. X *        much slower, but more accurately.  In most
  879. X *        cases, fast should be non-zero, as the error
  880. X *        introduced by the approximation is usually
  881. X *        small.  'Fast' is stored as an integer.
  882. X *
  883. X * colorquant returns the number of colors to which the image was
  884. X * quantized.
  885. X */
  886. X
  887. /*  
  888. X  March 1990
  889. X
  890. X  This routine was radically changed from Craig colorquant routine to
  891. X  support my MIFF image format.  
  892. X
  893. X  cristy@dupont.com
  894. */
  895. /*
  896. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  897. %                                                                             %
  898. %                                                                             %
  899. %                                                                             %
  900. %  Q u a n t i z e                                                            %
  901. %                                                                             %
  902. %                                                                             %
  903. %                                                                             %
  904. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  905. %
  906. %  Function Quantize takes a 24 bit image and reduces the number of colors
  907. %  so it can be displayed on raster device with less bits per pixel.  In most
  908. %  instances, the quantized image closely resembles the original reference
  909. %  image.
  910. %
  911. %  The format of the Quantize routine is:
  912. %
  913. %      colors=Quantize(image,number_colors,tree_depth,dither,optimal)
  914. %
  915. %  A description of each parameter follows.
  916. %
  917. %    o colors:  The Quantize function returns this integer
  918. %      value.  It is the actual number of colors allocated in the
  919. %      colormap.  Note, the actual number of colors allocated may be less
  920. %      than the number of colors requested, but never more.
  921. %
  922. %    o image:  Specifies a pointer to an Image structure;  returned from
  923. %      ReadImage.
  924. %
  925. %    o number_colors:  This integer value indicates the maximum number of
  926. %      colors in the quantized image or colormap.  The actual number of
  927. %      colors allocated to the colormap may be less than this value, but
  928. %      never more.  Note, the number of colors is restricted to a value
  929. %      less than or equal to 65536 if the continuous_tone parameter has a
  930. %      value of zero.
  931. %
  932. %    o tree_depth:  Normally, this integer value is zero or one.  A zero or
  933. %      one tells Quantize to choose a optimal tree depth of Log4(number_colors).
  934. %      A tree of this depth generally allows the best representation of the
  935. %      reference image with the least amount of memory and the fastest
  936. %      computational speed.  In some cases, such as an image with low color
  937. %      dispersion (a few number of colors), a value other than
  938. %      Log4(number_colors) is required.  To expand the color tree completely,
  939. %      use a value of 8.
  940. %
  941. %    o dither:  Set this integer value to something other than zero to
  942. %      dither the quantized image.  The basic strategy of dithering is to
  943. %      trade intensity resolution for spatial resolution by averaging the
  944. %      intensities of several neighboring pixels.  Images which suffer
  945. %      from severe contouring when quantized can be improved with the
  946. %      technique of dithering.  Severe contouring generally occurs when
  947. %      quantizing to very few colors, or to a poorly-chosen colormap.
  948. %      Note, dithering is a computationally expensive process and will
  949. %      increase processing time significantly.
  950. %
  951. %    o optimal:  An unsigned integer value greater than zero indicates that
  952. %      the optimal representation of the reference image should be returned.
  953. %
  954. %
  955. */
  956. unsigned int Quantize(image,number_colors,tree_depth,dither,optimal)
  957. Image
  958. X  *image;
  959. X
  960. unsigned int
  961. X  number_colors,
  962. X  tree_depth,
  963. X  dither,
  964. X  optimal;
  965. {
  966. X  Box  
  967. X    *Boxes;     /* Array of color boxes. */
  968. X
  969. X  extern unsigned int
  970. X    DitherImage();
  971. X
  972. X  float  
  973. X    Cfactor;    /* Conversion factor */
  974. X
  975. X  int  
  976. X    i,          /* Counter */
  977. X    OutColors,  /* # of entries computed */
  978. X    Colormax;   /* quantized full-intensity */ 
  979. X
  980. X  register unsigned short
  981. X    index;
  982. X
  983. X  RunlengthPacket
  984. X    *p;
  985. X
  986. X  unsigned short 
  987. X    *rgbmap;
  988. X
  989. X  if (number_colors > MaxColormapSize)
  990. X    number_colors=MaxColormapSize;
  991. X  if (tree_depth > 1)
  992. X    tree_depth=Min(tree_depth,8);
  993. X  else
  994. X    if (number_colors > 1024)
  995. X      tree_depth=5;
  996. X    else
  997. X      tree_depth=6;
  998. X  ColormaxI = 1 << tree_depth;  /* 2 ^ Bits */
  999. X  Colormax = ColormaxI - 1;
  1000. X  Bits = tree_depth;
  1001. X  NPixels = image->columns*image->rows;
  1002. X  Cfactor = (float)FULLINTENSITY / Colormax;
  1003. X  Histogram = (unsigned long *)
  1004. X    calloc(ColormaxI*ColormaxI*ColormaxI,sizeof(long));
  1005. X  rgbmap = (unsigned short *)
  1006. X    calloc(ColormaxI*ColormaxI*ColormaxI,sizeof(unsigned short));
  1007. X  Boxes = (Box *)malloc(number_colors * sizeof(Box));
  1008. X  if ((Histogram == NULL) || (rgbmap == NULL) || (Boxes == NULL))
  1009. X    {
  1010. X      (void) fprintf(stderr,"Can't continue, not enough memory\n");
  1011. X      exit(1);
  1012. X    }
  1013. X  QuantHistogram(image, &Boxes[0]);
  1014. X  OutColors = CutBoxes(Boxes, (int) number_colors);
  1015. X  /*
  1016. X   * We now know the set of representative colors.  We now
  1017. X   * must fill in the colormap and convert the representatives
  1018. X   * from their 'prequantized' range to 0-FULLINTENSITY.
  1019. X   */
  1020. X  image->colors=OutColors;
  1021. X  for (i = 0; i < image->colors; i++) 
  1022. X  {
  1023. X    image->colormap[i].red=(unsigned char) (Boxes[i].mean[REDI]*Cfactor+0.5);
  1024. X    image->colormap[i].green=(unsigned char)
  1025. X      (Boxes[i].mean[GREENI]*Cfactor+0.5);
  1026. X    image->colormap[i].blue=(unsigned char) (Boxes[i].mean[BLUEI]*Cfactor+0.5);
  1027. X  }
  1028. X  if (dither)
  1029. X    dither=!DitherImage(image);
  1030. X  if (!dither)
  1031. X    {
  1032. X      ComputeRGBMap(Boxes, OutColors, rgbmap, (int) tree_depth, !optimal);
  1033. X      p=image->pixels;
  1034. X      for (i=0; i < image->packets; i++)
  1035. X      {
  1036. X        index=(rgbmap[((((p->red >> (8-Bits))<<Bits) | 
  1037. X          (p->green >> (8-Bits)))<<Bits) | (p->blue >> (8-Bits))]);
  1038. X        p->index=index;
  1039. X        p++;
  1040. X      }
  1041. X    }
  1042. X  free((char *)Histogram);
  1043. X  free((char *)Boxes);
  1044. X  free((char *)rgbmap);
  1045. X  return((unsigned int) OutColors);  /* Return # of colormap entries */
  1046. }
  1047. X
  1048. /*
  1049. X * Compute the histogram of the image as well as the projected frequency
  1050. X * arrays for the first world-encompassing box.
  1051. X */
  1052. static void QuantHistogram(image, box)
  1053. Image
  1054. X  *image;
  1055. Box *box;
  1056. {
  1057. X  unsigned long *rf, *gf, *bf, i;
  1058. X  RunlengthPacket 
  1059. X    *p;
  1060. X
  1061. X  rf = box->freq[0];
  1062. X  gf = box->freq[1];
  1063. X  bf = box->freq[2];
  1064. X
  1065. X  /*
  1066. X   * Zero-out the projected frequency arrays of the largest box.
  1067. X   * We compute both the histogram and the proj. frequencies of
  1068. X   * the first box at the same time to save a pass through the
  1069. X   * entire image. 
  1070. X   */
  1071. X  for (i=0; i < ColormaxI; i++)
  1072. X  {
  1073. X    rf[i]=0;
  1074. X    gf[i]=0;
  1075. X    bf[i]=0;
  1076. X  }
  1077. X
  1078. X  /*
  1079. X    Modified to accept my runlength-encoded format.
  1080. X    
  1081. X    cristy@dupont.com
  1082. X  */
  1083. X  p=image->pixels;
  1084. X  for (i = 0; i < image->packets; i++) {
  1085. X    rf[p->red >> (8-Bits)]+=(p->length+1);
  1086. X    gf[p->green >> (8-Bits)]+=(p->length+1);
  1087. X    bf[p->blue >> (8-Bits)]+=(p->length+1);
  1088. X    Histogram[((((p->red >> (8-Bits))<<Bits)|(p->green >> (8-Bits)))<<Bits)|
  1089. X      (p->blue >> (8-Bits))]+=(p->length+1);
  1090. X    p++;
  1091. X  }
  1092. }
  1093. X
  1094. /*
  1095. X * Iteratively cut the boxes.
  1096. X */
  1097. static int CutBoxes(boxes, colors) 
  1098. Box  *boxes;
  1099. int  colors;
  1100. {
  1101. X  int curbox;
  1102. X
  1103. X  boxes[0].low[REDI] = boxes[0].low[GREENI] = boxes[0].low[BLUEI] = 0;
  1104. X  boxes[0].high[REDI] = boxes[0].high[GREENI] =
  1105. X            boxes[0].high[BLUEI] = ColormaxI;
  1106. X  boxes[0].weight = NPixels;
  1107. X
  1108. X  BoxStats(&boxes[0]);
  1109. X
  1110. X  for (curbox = 1; curbox < colors; curbox++) {
  1111. X    if (CutBox(&boxes[GreatestVariance(boxes, curbox)],
  1112. X         &boxes[curbox]) == FALSE)
  1113. X        break;
  1114. X  }
  1115. X  return curbox;
  1116. }
  1117. X
  1118. /*
  1119. X * Return the number of the box in 'boxes' with the greatest variance.
  1120. X * Restrict the search to those boxes with indices between 0 and n-1.
  1121. X */
  1122. static int GreatestVariance(boxes, n)
  1123. Box *boxes;
  1124. int n;
  1125. {
  1126. X  register int i, whichbox = 0;
  1127. X  double max;
  1128. X
  1129. X  max = -1;
  1130. X  for (i = 0; i < n; i++) {
  1131. X    if (boxes[i].weightedvar > max) {
  1132. X      max = boxes[i].weightedvar;
  1133. X      whichbox = i;
  1134. X    }
  1135. X  }
  1136. X  return whichbox;
  1137. }
  1138. X
  1139. /*
  1140. X * Compute mean and weighted variance of the given box.
  1141. X */
  1142. static void BoxStats(box)
  1143. register Box *box;
  1144. {
  1145. X  register int i, color;
  1146. X  unsigned long *freq;
  1147. X  float mean; 
  1148. X  double var;
  1149. X
  1150. X  if(box->weight == 0) {
  1151. X    box->weightedvar = 0;
  1152. X    return;
  1153. X  }
  1154. X
  1155. X  box->weightedvar = 0.;
  1156. X  for (color = 0; color < 3; color++) {
  1157. X    var = mean = 0;
  1158. X    i = box->low[color];
  1159. X    freq = &box->freq[color][i];
  1160. X    for (; i < box->high[color]; i++, freq++) {
  1161. X      mean += i * *freq;
  1162. X      var += i*i* *freq;
  1163. X    }
  1164. X    box->mean[color] = mean / (float)box->weight;
  1165. X    box->weightedvar += var - box->mean[color]*box->mean[color]*
  1166. X          (float)box->weight;
  1167. X  }
  1168. X  box->weightedvar /= NPixels;
  1169. }
  1170. X
  1171. /*
  1172. X * Cut the given box.  Returns TRUE if the box could be cut, FALSE otherwise.
  1173. X */
  1174. static int CutBox(box, newbox)
  1175. Box *box, *newbox;
  1176. {
  1177. X  int i;
  1178. X  double totalvar[3];
  1179. X  Box newboxes[3][2];
  1180. X
  1181. X  if (box->weightedvar == 0. || box->weight == 0)
  1182. X    /*
  1183. X     * Can't cut this box.
  1184. X     */
  1185. X    return FALSE;
  1186. X
  1187. X  /*
  1188. X   * Find 'optimal' cutpoint along each of the red, green and blue
  1189. X   * axes.  Sum the variances of the two boxes which would result
  1190. X   * by making each cut and store the resultant boxes for 
  1191. X   * (possible) later use.
  1192. X   */
  1193. X  for (i = 0; i < 3; i++) {
  1194. X    if (FindCutpoint(box, i, &newboxes[i][0], &newboxes[i][1]))
  1195. X      totalvar[i] = newboxes[i][0].weightedvar +
  1196. X        newboxes[i][1].weightedvar;
  1197. X    else
  1198. X      totalvar[i] = HUGE;
  1199. X  }
  1200. X
  1201. X  /*
  1202. X   * Find which of the three cuts minimized the total variance
  1203. X   * and make that the 'real' cut.
  1204. X   */
  1205. X  if (totalvar[REDI] <= totalvar[GREENI] &&
  1206. X      totalvar[REDI] <= totalvar[BLUEI]) {
  1207. X    *box = newboxes[REDI][0];
  1208. X    *newbox = newboxes[REDI][1];
  1209. X  } else if (totalvar[GREENI] <= totalvar[REDI] &&
  1210. X     totalvar[GREENI] <= totalvar[BLUEI]) {
  1211. X    *box = newboxes[GREENI][0];
  1212. X    *newbox = newboxes[GREENI][1];
  1213. X  } else {
  1214. X    *box = newboxes[BLUEI][0];
  1215. X    *newbox = newboxes[BLUEI][1];
  1216. X  }
  1217. X
  1218. X  return TRUE;
  1219. }
  1220. X
  1221. /*
  1222. X * Compute the 'optimal' cutpoint for the given box along the axis
  1223. X * indicated by 'color'.  Store the boxes which result from the cut
  1224. X * in newbox1 and newbox2.
  1225. X */
  1226. static int FindCutpoint(box, color, newbox1, newbox2)
  1227. Box *box, *newbox1, *newbox2;
  1228. int color;
  1229. {
  1230. X  float u, v, max;
  1231. X  int i, maxindex, minindex, cutpoint;
  1232. X  unsigned long optweight, curweight;
  1233. X
  1234. X  if (box->low[color] + 1 == box->high[color])
  1235. X    return FALSE;  /* Cannot be cut. */
  1236. X  minindex = (int)((box->low[color] + box->mean[color]) * 0.5);
  1237. X  maxindex = (int)((box->mean[color] + box->high[color]) * 0.5);
  1238. X
  1239. X  cutpoint = minindex;
  1240. X  optweight = box->weight;
  1241. X
  1242. X  curweight = 0.;
  1243. X  for (i = box->low[color] ; i < minindex ; i++)
  1244. X    curweight += box->freq[color][i];
  1245. X  u = 0.;
  1246. X  max = -1;
  1247. X  for (i = minindex; i <= maxindex ; i++) {
  1248. X    curweight += box->freq[color][i];
  1249. X    if (curweight == box->weight)
  1250. X      break;
  1251. X    u += (float)(i * box->freq[color][i]) /
  1252. X          (float)box->weight;
  1253. X    v = ((float)curweight / (float)(box->weight-curweight)) *
  1254. X        (box->mean[color]-u)*(box->mean[color]-u);
  1255. X    if (v > max) {
  1256. X      max = v;
  1257. X      cutpoint = i;
  1258. X      optweight = curweight;
  1259. X    }
  1260. X  }
  1261. X  cutpoint++;
  1262. X  *newbox1 = *newbox2 = *box;
  1263. X  newbox1->weight = optweight;
  1264. X  newbox2->weight -= optweight;
  1265. X  newbox1->high[color] = cutpoint;
  1266. X  newbox2->low[color] = cutpoint;
  1267. X  UpdateFrequencies(newbox1, newbox2);
  1268. X  BoxStats(newbox1);
  1269. X  BoxStats(newbox2);
  1270. X
  1271. X  return TRUE;  /* Found cutpoint. */
  1272. }
  1273. X
  1274. /*
  1275. X * Update projected frequency arrays for two boxes which used to be
  1276. X * a single box.
  1277. X */
  1278. static void UpdateFrequencies(box1, box2)
  1279. register Box *box1, *box2;
  1280. {
  1281. X  register unsigned long myfreq, *h;
  1282. X  register int b, g, i, r;
  1283. X  int roff;
  1284. X
  1285. X  for (i=0; i < ColormaxI; i++)
  1286. X  {
  1287. X    box1->freq[0][i]=0;
  1288. X    box1->freq[1][i]=0;
  1289. X    box1->freq[2][i]=0;
  1290. X  }
  1291. X
  1292. X  for (r = box1->low[0]; r < box1->high[0]; r++) {
  1293. X    roff = r << Bits;
  1294. X    for (g = box1->low[1];g < box1->high[1]; g++) {
  1295. X      b = box1->low[2];
  1296. X      h = Histogram + (((roff | g) << Bits) | b);
  1297. X      for (; b < box1->high[2]; b++) {
  1298. X        if ((myfreq = *h++) == 0)
  1299. X          continue;
  1300. X        box1->freq[0][r] += myfreq;
  1301. X        box1->freq[1][g] += myfreq;
  1302. X        box1->freq[2][b] += myfreq;
  1303. X        box2->freq[0][r] -= myfreq;
  1304. X        box2->freq[1][g] -= myfreq;
  1305. X        box2->freq[2][b] -= myfreq;
  1306. X      }
  1307. X    }
  1308. X  }
  1309. }
  1310. X
  1311. /*
  1312. X * Compute RGB to colormap index map.
  1313. X */
  1314. static void ComputeRGBMap(boxes, colors, rgbmap, bits, fast)
  1315. Box *boxes;
  1316. int colors;
  1317. unsigned short *rgbmap ;
  1318. int bits, fast;
  1319. {
  1320. X  register int i;
  1321. X
  1322. X  if (fast) {
  1323. X    /*
  1324. X     * The centroid of each box serves as the representative
  1325. X     * for each color in the box.
  1326. X     */
  1327. X    for (i = 0; i < colors; i++)
  1328. X      SetRGBmap(i, &boxes[i], rgbmap, bits);
  1329. X  } else
  1330. X    /*
  1331. X     * Find the 'nearest' representative for each
  1332. X     * pixel.
  1333. X     */
  1334. X    find_colors(boxes, colors, rgbmap, bits);
  1335. }
  1336. X
  1337. /*
  1338. X * Make the centroid of "boxnum" serve as the representative for
  1339. X * each color in the box.
  1340. X */
  1341. static void SetRGBmap(boxnum, box, rgbmap, bits)
  1342. int boxnum;
  1343. Box *box;
  1344. unsigned short *rgbmap;
  1345. int bits;
  1346. {
  1347. X  register int r, g, b;
  1348. X  
  1349. X  for (r = box->low[REDI]; r < box->high[REDI]; r++) {
  1350. X    for (g = box->low[GREENI]; g < box->high[GREENI]; g++) {
  1351. X      for (b = box->low[BLUEI]; b < box->high[BLUEI]; b++) {
  1352. X        rgbmap[(((r<<bits)|g)<<bits)|b]=(unsigned short)boxnum;
  1353. X      }
  1354. X    }
  1355. X  }
  1356. }
  1357. /*
  1358. X * Form colormap and NearestColor arrays.
  1359. X */
  1360. static void find_colors(boxes, colors, rgbmap, bits)
  1361. int colors;
  1362. Box *boxes;
  1363. unsigned short *rgbmap;
  1364. int bits;
  1365. {
  1366. X  register int i;
  1367. X  int num, *neighbors;
  1368. X
  1369. X  neighbors = (int *)malloc((unsigned int) colors * sizeof(int));
  1370. X
  1371. X  /*
  1372. X   * Form map of representative (nearest) colors.
  1373. X   */
  1374. X  for (i = 0; i < colors; i++) {
  1375. X    /*
  1376. X     * Create list of candidate neighbors and
  1377. X     * find closest representative for each
  1378. X     * color in the box.
  1379. X     */
  1380. X    num = getneighbors(boxes, i, neighbors, colors);
  1381. X    makenearest(boxes, i, num, neighbors, rgbmap, bits);
  1382. X  }
  1383. X  free((char *)neighbors);
  1384. }
  1385. X
  1386. /*
  1387. X * In order to minimize our search for 'best representative', we form the
  1388. X * 'neighbors' array.  This array contains the number of the boxes whose
  1389. X * centroids *might* be used as a representative for some color in the
  1390. X * current box.  We need only consider those boxes whose centroids are closer
  1391. X * to one or more of the current box's corners than is the centroid of the
  1392. X * current box. 'Closeness' is measured by Euclidean distance.
  1393. X */
  1394. static int getneighbors(boxes, num, neighbors, colors)
  1395. Box *boxes;
  1396. int num, colors, *neighbors;
  1397. {
  1398. X  register int i, j;
  1399. X  Box *bp;
  1400. X  float dist, LowR, LowG, LowB, HighR, HighG, HighB, ldiff, hdiff;
  1401. X
  1402. X  bp = &boxes[num];
  1403. X
  1404. X  ldiff = bp->low[REDI] - bp->mean[REDI];
  1405. X  ldiff *= ldiff;
  1406. X  hdiff = bp->high[REDI] - bp->mean[REDI];
  1407. X  hdiff *= hdiff;
  1408. X  dist = MAX(ldiff, hdiff);
  1409. X
  1410. X  ldiff = bp->low[GREENI] - bp->mean[GREENI];
  1411. X  ldiff *= ldiff;
  1412. X  hdiff = bp->high[GREENI] - bp->mean[GREENI];
  1413. X  hdiff *= hdiff;
  1414. X  dist += MAX(ldiff, hdiff);
  1415. X
  1416. X  ldiff = bp->low[BLUEI] - bp->mean[BLUEI];
  1417. X  ldiff *= ldiff;
  1418. X  hdiff = bp->high[BLUEI] - bp->mean[BLUEI];
  1419. X  hdiff *= hdiff;
  1420. X  dist += MAX(ldiff, hdiff);
  1421. X
  1422. #ifdef IRIS
  1423. X  dist = fsqrt(dist);
  1424. #else
  1425. X  dist = (float)sqrt((double)dist);
  1426. #endif
  1427. X
  1428. X  /*
  1429. X   * Loop over all colors in the colormap, the ith entry of which
  1430. X   * corresponds to the ith box.
  1431. X   *
  1432. X   * If the centroid of a box is as close to any corner of the
  1433. X   * current box as is the centroid of the current box, add that
  1434. X   * box to the list of "neighbors" of the current box.
  1435. X   */
  1436. X  HighR = (float)bp->high[REDI] + dist;
  1437. X  HighG = (float)bp->high[GREENI] + dist;
  1438. X  HighB = (float)bp->high[BLUEI] + dist;
  1439. X  LowR = (float)bp->low[REDI] - dist;
  1440. X  LowG = (float)bp->low[GREENI] - dist;
  1441. X  LowB = (float)bp->low[BLUEI] - dist;
  1442. X  for (i = j = 0, bp = boxes; i < colors; i++, bp++) {
  1443. X    if (LowR <= bp->mean[REDI] && HighR >= bp->mean[REDI] &&
  1444. X        LowG <= bp->mean[GREENI] && HighG >= bp->mean[GREENI] &&
  1445. X        LowB <= bp->mean[BLUEI] && HighB >= bp->mean[BLUEI])
  1446. X      neighbors[j++] = i;
  1447. X  }
  1448. X
  1449. X  return j;  /* Return the number of neighbors found. */
  1450. }
  1451. X
  1452. /*
  1453. X * Assign representative colors to every pixel in a given box through
  1454. X * the construction of the NearestColor array.  For each color in the
  1455. X * given box, we look at the list of neighbors passed to find the
  1456. X * one whose centroid is closest to the current color.
  1457. X */
  1458. static int makenearest(boxes, boxnum, nneighbors, neighbors, rgbmap, bits)
  1459. Box *boxes;
  1460. int boxnum;
  1461. int nneighbors, *neighbors, bits;
  1462. unsigned short *rgbmap;
  1463. {
  1464. X  register int n, b, g, r;
  1465. X  double rdist, gdist, bdist, dist, mindist,total_dist;
  1466. X  int which, *np;
  1467. X  Box *box;
  1468. X  extern unsigned long *Histogram;
  1469. X
  1470. X  box = &boxes[boxnum];
  1471. X
  1472. X  for (r = box->low[REDI]; r < box->high[REDI]; r++) {
  1473. X    for (g = box->low[GREENI]; g < box->high[GREENI]; g++) {
  1474. X      for (b = box->low[BLUEI]; b < box->high[BLUEI]; b++) {
  1475. /*
  1476. X * The following two lines should be commented out if the RGBmap is going
  1477. X * to be used for images other than the one given.
  1478. X */
  1479. X        if (Histogram[(((r<<bits)|g)<<bits)|b] == 0)
  1480. X          continue;
  1481. X        mindist = HUGE;
  1482. X        /*
  1483. X         * Find the colormap entry which is
  1484. X         * closest to the current color.
  1485. X         */
  1486. X        np = neighbors;
  1487. X        for (n = 0; n < nneighbors; n++, np++) {
  1488. X          rdist = r-boxes[*np].mean[REDI];
  1489. X          gdist = g-boxes[*np].mean[GREENI];
  1490. X          dist = rdist*rdist;
  1491. X          total_dist = dist + gdist*gdist;
  1492. X          if (total_dist < dist)
  1493. X            continue;
  1494. X          bdist = b-boxes[*np].mean[BLUEI];
  1495. X          dist = total_dist + bdist*bdist;
  1496. X          if (dist >= total_dist)
  1497. X            if (dist < mindist) {
  1498. X              mindist = dist;
  1499. X              which = *np; 
  1500. X            }
  1501. X        }
  1502. X        /*
  1503. X         * The colormap entry closest to this
  1504. X         * color is used as a representative.
  1505. X         */
  1506. X        rgbmap[(((r<<bits)|g)<<bits)|b] = (unsigned short) which;
  1507. X      }
  1508. X    }
  1509. X  }
  1510. }
  1511. SHAR_EOF
  1512. chmod 0755 ImageMagick/kolb.c ||
  1513. echo 'restore of ImageMagick/kolb.c failed'
  1514. Wc_c="`wc -c < 'ImageMagick/kolb.c'`"
  1515. test 22830 -eq "$Wc_c" ||
  1516.     echo 'ImageMagick/kolb.c: original size 22830, current size' "$Wc_c"
  1517. rm -f _shar_wnt_.tmp
  1518. fi
  1519. # ============= ImageMagick/quantize.c ==============
  1520. if test -f 'ImageMagick/quantize.c' -a X"$1" != X"-c"; then
  1521.     echo 'x - skipping ImageMagick/quantize.c (File already exists)'
  1522.     rm -f _shar_wnt_.tmp
  1523. else
  1524. > _shar_wnt_.tmp
  1525. echo 'x - extracting ImageMagick/quantize.c (Text)'
  1526. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/quantize.c' &&
  1527. /*
  1528. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1529. %                                                                             %
  1530. %                                                                             %
  1531. %                                                                             %
  1532. %           QQQ   U   U   AAA   N   N  TTTTT  IIIII   ZZZZZ  EEEEE            %
  1533. %          Q   Q  U   U  A   A  NN  N    T      I        ZZ  E                %
  1534. %          Q   Q  U   U  AAAAA  N N N    T      I      ZZZ   EEEEE            %
  1535. %          Q  QQ  U   U  A   A  N  NN    T      I     ZZ     E                %
  1536. %           QQQQ   UUU   A   A  N   N    T    IIIII   ZZZZZ  EEEEE            %
  1537. %                                                                             %
  1538. %                                                                             %
  1539. %                        Quantize a Color Image                               %
  1540. %                                                                             %
  1541. %                                                                             %
  1542. %                                                                             %
  1543. %                           Software Design                                   %
  1544. %                             John Cristy                                     %
  1545. %                            October  1990                                    %
  1546. %                                                                             %
  1547. %                                                                             %
  1548. %  Copyright 1990 E. I. Dupont de Nemours & Company                           %
  1549. %                                                                             %
  1550. %  Permission to copy, modify, distribute, or sell this software or its       %
  1551. %  documentation for any purpose is hereby denied without specific, written   %
  1552. %  prior permission from E. I. Dupont de Nemours & Company.                   %
  1553. %                                                                             %
  1554. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  1555. %  to this software, including all implied warranties of merchantability      %
  1556. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  1557. %  liable for any special, indirect or consequential damages or any           %
  1558. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  1559. %  in an action of contract, negligence or other tortious action, arising     %
  1560. %  out of or in connection with the use or performance of this software.      %
  1561. %                                                                             %
  1562. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1563. %
  1564. %  Realism in computer graphics typically requires using 24 bits/pixel to
  1565. %  generate an image.  Yet many graphic display devices do not contain
  1566. %  the amount of memory necessary to match the spatial and color
  1567. %  resolution of the human eye.  The QUANTIZE program takes a 24 bit
  1568. %  image and reduces the number of colors so it can be displayed on
  1569. %  raster device with less bits per pixel.  In most instances, the
  1570. %  quantized image closely resembles the original reference image.
  1571. %
  1572. %  A reduction of colors in an image is also desirable for image
  1573. %  transmission and real-time animation.
  1574. %
  1575. %  Function Quantize takes a standard RGB or monochrome images and quantizes
  1576. %  them down to some fixed number of colors.
  1577. %
  1578. %
  1579. */
  1580. X
  1581. /*
  1582. X  Include declarations.
  1583. */
  1584. #include "display.h"
  1585. #include "image.h"
  1586. X
  1587. unsigned int
  1588. X  squares[MaxRgb+MaxRgb+1];
  1589. X
  1590. /*
  1591. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1592. %                                                                             %
  1593. %                                                                             %
  1594. %                                                                             %
  1595. %  C l o s e s t C o l o r                                                    %
  1596. %                                                                             %
  1597. %                                                                             %
  1598. %                                                                             %
  1599. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1600. %
  1601. %  Function ClosestColor traverses the color cube tree at a particular node
  1602. %  and determines which colormap entry best represents the input color.
  1603. %
  1604. %  The format of the ClosestColor routine is: 
  1605. %
  1606. %      ClosestColor(node)
  1607. %
  1608. %  A description of each parameter follows.
  1609. %
  1610. %    o node: The address of a structure of type Node which points to a
  1611. %      node in the color cube tree that is to be pruned.
  1612. %
  1613. %
  1614. */
  1615. static int ClosestColor(image,red,green,blue)
  1616. Image
  1617. X  *image;
  1618. X
  1619. register unsigned char
  1620. X  red,
  1621. X  green,
  1622. X  blue;
  1623. {
  1624. X  register ColorPacket
  1625. X    *p;
  1626. X
  1627. X  register int
  1628. X    i;
  1629. X
  1630. X  register int
  1631. X    color_number;
  1632. X
  1633. X  unsigned long
  1634. X    blue_distance,
  1635. X    distance,
  1636. X    green_distance,
  1637. X    minimum_distance,
  1638. X    red_distance;
  1639. X
  1640. X  p=image->colormap;
  1641. X  minimum_distance=(~0);
  1642. X  for (i=0; i < image->colors; i++)
  1643. X  {
  1644. X    red_distance=red-p->red+MaxRgb;
  1645. X    green_distance=green-p->green+MaxRgb;
  1646. X    blue_distance=blue-p->blue+MaxRgb;
  1647. X    distance=squares[red_distance]+squares[green_distance]+
  1648. X      squares[blue_distance];
  1649. X    if (distance < minimum_distance)
  1650. X      {
  1651. X        minimum_distance=distance;
  1652. X        color_number=i;
  1653. X        if (distance == 0)
  1654. X          break;
  1655. X      }
  1656. X    p++;
  1657. X  }
  1658. X  return(color_number);
  1659. }
  1660. X
  1661. /*
  1662. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1663. %                                                                             %
  1664. %                                                                             %
  1665. %                                                                             %
  1666. %  D i t h e r I m a g e                                                      %
  1667. %                                                                             %
  1668. %                                                                             %
  1669. %                                                                             %
  1670. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1671. %
  1672. %  Procedure DitherImage uses the Floyd-Steinberg algorithm to dither the
  1673. %  image.  Refer to "An Adaptive Algorithm for Spatial GreySscale", Robert W.
  1674. %  Floyd and Louis Steinberg, Proceedings of the S.I.D., Volume 17(2), 1976.
  1675. %
  1676. %  First find the closest representation to the reference pixel color  in the 
  1677. %  colormap, the node pixel is assigned this color.  Next, the colormap  color 
  1678. %  is subtracted from the reference pixels color, this represents the
  1679. %  quantization error.  Various amounts of this error are added to the pixels
  1680. %  ahead and below the node pixel to correct for this error.  The error
  1681. %  proportions are: 
  1682. %
  1683. %            P     7/16
  1684. %      3/16  5/16  1/16
  1685. %
  1686. %  The error is distributed left-to-right for even scanlines and right-to-left
  1687. %  for odd scanlines.
  1688. %
  1689. %  The format of the DitherImage routine is: 
  1690. %
  1691. %      DitherImage(image)
  1692. %
  1693. %  A description of each parameter follows.
  1694. %
  1695. %    o image: Specifies a pointer to an Image structure;  returned from
  1696. %      ReadImage.
  1697. %
  1698. %
  1699. */
  1700. unsigned int DitherImage(image)
  1701. Image
  1702. X  *image;
  1703. {
  1704. X  typedef struct _ScaledColorPacket
  1705. X  {
  1706. X    long int
  1707. X      red,
  1708. X      green,
  1709. X      blue;
  1710. X  } ScaledColorPacket;
  1711. X
  1712. X  ColorPacket
  1713. X    *dithered_pixels;
  1714. X
  1715. X  int
  1716. X    *cache,
  1717. X    j;
  1718. X
  1719. X  register ColorPacket
  1720. X    *q;
  1721. X
  1722. X  register ScaledColorPacket
  1723. X    *cs,
  1724. X    *ns;
  1725. X
  1726. X  register int
  1727. X    blue_error,
  1728. X    green_error,
  1729. X    red_error,
  1730. X    step;
  1731. X
  1732. X  register RunlengthPacket
  1733. X    *p;
  1734. X
  1735. X  ScaledColorPacket
  1736. X    *scanline;
  1737. X
  1738. X  unsigned int
  1739. X    i,
  1740. X    x,
  1741. X    y;
  1742. X
  1743. X  for (j=(-MaxRgb); j <= MaxRgb; j++)
  1744. X    squares[j+MaxRgb]=j*j;
  1745. X  /*
  1746. X    Allocate the cache & scanline buffers to keep track of quantization error.
  1747. X  */
  1748. X  dithered_pixels=(ColorPacket *)
  1749. X    malloc(image->columns*image->rows*sizeof(ColorPacket));
  1750. X  cache=(int *) malloc((1 << 18)*sizeof(int));
  1751. X  scanline=(ScaledColorPacket *)
  1752. X    malloc(2*(image->columns+2)*sizeof(ScaledColorPacket));
  1753. X  if ((dithered_pixels == (ColorPacket *) NULL) || (cache == (int *) NULL) || 
  1754. X      (scanline == (ScaledColorPacket *) NULL))
  1755. X    {
  1756. X      Warning("unable to dither image","memory allocation failed");
  1757. X      return(True);
  1758. X    }
  1759. X  /*
  1760. X    Initialize cache buffer.
  1761. X  */
  1762. X  for (i=0; i < (1 << 18); i++)
  1763. X    cache[i]=(-1);
  1764. X  /*
  1765. X    Preload first scanline.
  1766. X  */
  1767. X  p=image->pixels;
  1768. X  image->runlength=p->length+1;
  1769. X  cs=scanline+1;
  1770. X  for (i=0; i < image->columns; i++)
  1771. X  {
  1772. X    if (image->runlength > 0)
  1773. X      image->runlength--;
  1774. X    else
  1775. X      {
  1776. X        p++;
  1777. X        image->runlength=p->length;
  1778. X      }
  1779. X    cs->red=p->red << 14;
  1780. X    cs->green=p->green << 14;
  1781. X    cs->blue=p->blue << 14;
  1782. X    cs++;
  1783. X  }
  1784. X  for (y=0; y < image->rows; y++)
  1785. X  {
  1786. X    /*
  1787. X      Read another scanline.
  1788. X    */
  1789. X    ns=scanline+(image->columns+2)*((y+1) % 2)+1;
  1790. X    if (y < (image->rows-1))
  1791. X      for (i=0; i < image->columns; i++)
  1792. X      {
  1793. X        if (image->runlength > 0)
  1794. X          image->runlength--;
  1795. X        else
  1796. X          {
  1797. X            p++;
  1798. X            image->runlength=p->length;
  1799. X          }
  1800. X        ns->red=p->red << 14;
  1801. X        ns->green=p->green << 14;
  1802. X        ns->blue=p->blue << 14;
  1803. X        ns++;
  1804. X      }
  1805. X    /*
  1806. X      Distribute error left-to-right for even scanlines and right-to-left for
  1807. X      odd scanlines.
  1808. X    */
  1809. X    q=dithered_pixels+image->columns*y+(y % 2 ? image->columns-1 : 0);
  1810. X    cs=scanline+((y+0) % 2 ? image->columns+2 : 0)+
  1811. X      (y % 2 ? image->columns-1 : 0)+1;
  1812. X    ns=scanline+((y+1) % 2 ? image->columns+2 : 0)+
  1813. X      (y % 2 ? image->columns-1 : 0)+1;
  1814. X    step=(y % 2 ? -1 : 1);
  1815. X    for (x=0; x < image->columns; x++)
  1816. X    {
  1817. X      if (cs->red < 0)
  1818. X        red_error=0;
  1819. X      else
  1820. X        if (cs->red > (MaxRgb << 14))
  1821. X          red_error=MaxRgb << 14;
  1822. X        else
  1823. X          red_error=cs->red;
  1824. X      if (cs->green < 0)
  1825. X        green_error=0;
  1826. X      else
  1827. X        if (cs->green > (MaxRgb << 14))
  1828. X          green_error=MaxRgb << 14;
  1829. X        else
  1830. X          green_error=cs->green;
  1831. X      if (cs->blue < 0)
  1832. X        blue_error=0;
  1833. X      else
  1834. X        if (cs->blue > (MaxRgb << 14))
  1835. X          blue_error=MaxRgb << 14;
  1836. X        else
  1837. X          blue_error=cs->blue;
  1838. X      q->red=(red_error+(1 << 13)-1) >> 14;
  1839. X      q->green=(green_error+(1 << 13)-1) >> 14;
  1840. X      q->blue=(blue_error+(1 << 13)-1) >> 14;
  1841. X      i=(q->red >> 2) << 12 | (q->green >> 2) << 6 | q->blue >> 2;
  1842. X      if (cache[i] < 0)
  1843. X        cache[i]=ClosestColor(image,q->red,q->green,q->blue);
  1844. X      q->index=(unsigned short) cache[i];
  1845. X      red_error-=image->colormap[q->index].red << 14;
  1846. X      green_error-=image->colormap[q->index].green << 14;
  1847. X      blue_error-=image->colormap[q->index].blue << 14;
  1848. X      q+=step;
  1849. X      /*
  1850. X        Propagate the error in these proportions: 
  1851. X                Q     7/16
  1852. X          3/16  5/16  1/16
  1853. X      */
  1854. X      cs+=step;
  1855. X      cs->red+=red_error*7 >> 4;
  1856. X      cs->green+=green_error*7 >> 4;
  1857. X      cs->blue+=blue_error*7 >> 4;
  1858. X      ns-=step;
  1859. X      ns->red+=red_error*3 >> 4;
  1860. X      ns->green+=green_error*3 >> 4;
  1861. X      ns->blue+=blue_error*3 >> 4;
  1862. X      ns+=step;
  1863. X      ns->red+=red_error*5 >> 4;
  1864. X      ns->green+=green_error*5 >> 4;
  1865. X      ns->blue+=blue_error*5 >> 4;
  1866. X      ns+=step;
  1867. X      ns->red+=(red_error-(red_error*15 >> 4));
  1868. X      ns->green+=(green_error-(green_error*15 >> 4));
  1869. X      ns->blue+=(blue_error-(blue_error*15 >> 4));
  1870. X    }
  1871. X  }
  1872. X  (void) free((char *) scanline);
  1873. X  (void) free((char *) cache);
  1874. X  /*
  1875. X    Convert dithered image to runlength-encoded pixels.
  1876. X  */
  1877. X  image->pixels=(RunlengthPacket *) realloc((char *) 
  1878. X    image->pixels,image->columns*image->rows*sizeof(RunlengthPacket));
  1879. X  if (image->pixels == (RunlengthPacket *) NULL)
  1880. X    {
  1881. X      Warning("unable to dither image","memory allocation failed");
  1882. X      return(True);
  1883. X    }
  1884. X  q=dithered_pixels;
  1885. X  image->packets=0;
  1886. X  p=image->pixels;
  1887. X  p->length=MaxRunlength;
  1888. X  for (i=0; i < (image->columns*image->rows); i++)
  1889. X  {
  1890. X    if ((q->red == p->red) && (q->green == p->green) &&
  1891. X        (q->blue == p->blue) && (p->length < MaxRunlength))
  1892. X       p->length++;
  1893. X     else
  1894. X       {
  1895. X         if (image->packets > 0)
  1896. X           p++;
  1897. X         image->packets++;
  1898. X         p->red=q->red;
  1899. X         p->green=q->green;
  1900. X         p->blue=q->blue;
  1901. X         p->index=q->index;
  1902. X         p->length=0;
  1903. X       }
  1904. X    q++;
  1905. X  }
  1906. X  (void) free((char *) dithered_pixels);
  1907. X  image->pixels=(RunlengthPacket *) 
  1908. X    realloc((char *) image->pixels,image->packets*sizeof(RunlengthPacket));
  1909. X  return(False);
  1910. }
  1911. X
  1912. /*
  1913. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1914. %                                                                             %
  1915. %                                                                             %
  1916. %                                                                             %
  1917. %  Q u a n t i z a t i o n E r r o r                                          %
  1918. %                                                                             %
  1919. %                                                                             %
  1920. %                                                                             %
  1921. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1922. %
  1923. %  Function QuantizationError measures the difference between the original
  1924. %  and quantized images.  This difference is the total quantization error.
  1925. %  The error is computed by summing over all pixels in an image the distance
  1926. %  squared in RGB space between each reference pixel value and its quantized
  1927. %  value.
  1928. %
  1929. %  The format of the QuantizationError routine is: 
  1930. %
  1931. %      QuantizationError(image,mean_error_per_pixel,
  1932. %        normalized_mean_square_error,normalized_maximum_square_error)
  1933. %
  1934. %  A description of each parameter follows.
  1935. %
  1936. %    o image: The address of a byte (8 bits) array of run-length
  1937. %      encoded pixel data of your reference image.  The sum of the
  1938. %      run-length counts in the reference image must be equal to or exceed
  1939. %      the number of pixels.
  1940. %
  1941. %    o mean_error_per_pixel: The address of an integer value.  The value
  1942. %      returned is the mean error for any single pixel in the image.
  1943. %
  1944. %    o normalized_mean_square_error: The address of a real value.  The value
  1945. %      returned is the normalized mean quantization error for any single
  1946. %      pixel in the image.  This distance measure is normalized to a
  1947. %      range between 0 and 1.  It is independent of the range of red,
  1948. %      green, and blue values in your image.
  1949. %
  1950. %    o normalized_maximum_square_error: The address of a real value.  The value
  1951. %      returned is the normalized maximum quantization error for any
  1952. %      single pixel in the image.  This distance measure is normalized to
  1953. %      a range between 0 and 1.  It is independent of the range of red,
  1954. %      green, and blue values in your image.
  1955. %
  1956. %
  1957. */
  1958. void QuantizationError(image,mean_error_per_pixel,normalized_mean_square_error,
  1959. X  normalized_maximum_square_error)
  1960. Image
  1961. X  *image;
  1962. X
  1963. unsigned int
  1964. X  *mean_error_per_pixel;
  1965. X
  1966. double
  1967. X  *normalized_mean_square_error,
  1968. X  *normalized_maximum_square_error;
  1969. {
  1970. X  register int
  1971. X    i;
  1972. X
  1973. X  register RunlengthPacket
  1974. X    *p;
  1975. X
  1976. X  register unsigned long
  1977. X    blue_distance,
  1978. X    green_distance,
  1979. X    red_distance;
  1980. X
  1981. X  unsigned long
  1982. X    distance,
  1983. X    maximum_error_per_pixel,
  1984. X    total_error;
  1985. X
  1986. X  /*
  1987. X    For each pixel, collect error statistics.
  1988. X  */
  1989. X  for (i=(-MaxRgb); i <= MaxRgb; i++)
  1990. X    squares[i+MaxRgb]=i*i;
  1991. X  maximum_error_per_pixel=0;
  1992. X  total_error=0;
  1993. X  p=image->pixels;
  1994. X  for (i=0; i < image->packets; i++)
  1995. X  {
  1996. X    red_distance=p->red-image->colormap[p->index].red+MaxRgb;
  1997. X    green_distance=p->green-image->colormap[p->index].green+MaxRgb;
  1998. X    blue_distance=p->blue-image->colormap[p->index].blue+MaxRgb;
  1999. X    distance=squares[red_distance]+squares[green_distance]+
  2000. X      squares[blue_distance];
  2001. X    total_error+=(distance*(p->length+1));
  2002. X    if (distance > maximum_error_per_pixel)
  2003. X      maximum_error_per_pixel=distance;
  2004. X    p++;
  2005. X  }
  2006. X  /*
  2007. X    Compute final error statistics.
  2008. X  */
  2009. X  *mean_error_per_pixel=total_error/(image->columns*image->rows);
  2010. X  *normalized_mean_square_error=((double) *mean_error_per_pixel)/
  2011. X    (3.0*MaxRgb*MaxRgb);
  2012. X  *normalized_maximum_square_error=((double) maximum_error_per_pixel)/
  2013. X    (3.0*MaxRgb*MaxRgb);
  2014. }
  2015. X
  2016. /*
  2017. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2018. %                                                                             %
  2019. %                                                                             %
  2020. %                                                                             %
  2021. %   Q u a n t i z e I m a g e                                                 %
  2022. %                                                                             %
  2023. %                                                                             %
  2024. %                                                                             %
  2025. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2026. %
  2027. %  QuantizeImage analyzes the colors within a reference image and chooses a
  2028. %  fixed number of colors to represent the image.  The goal of the algorithm
  2029. %  is to minimize the difference between the input and output image while
  2030. %  minimizing the processing time.
  2031. %
  2032. %  The format of the QuantizeImage routine is: 
  2033. %
  2034. %      QuantizeImage(image,number_colors,tree_depth,dither,optimal)
  2035. %
  2036. %  A description of each parameter follows: 
  2037. %
  2038. %    o image: Specifies a pointer to an Image structure;  returned from
  2039. %      ReadImage.
  2040. %
  2041. %    o number_colors: This integer value indicates the maximum number of
  2042. %      colors in the quantized image or colormap.  The actual number of colors
  2043. %      allocated to the colormap may be less than this value, but never more.
  2044. %      Note, the number of colors is restricted to a value less than or equal
  2045. %      to 65536 if the quantized image is not DirectClass.
  2046. %
  2047. %    o tree_depth: Normally, this integer value is zero or one.  A zero or
  2048. %      one tells QUANTIZE to choose a optimal tree depth.  An optimal depth
  2049. %      generally allows the best representation of the reference image with the
  2050. %      fastest computational speed and the least amount of memory.  However,
  2051. %      the default depth is inappropriate for some images.  To assure the best
  2052. %      representation, try values between 2 and 8 for this parameter.
  2053. %
  2054. %    o dither: Set this integer value to something other than zero to
  2055. %      dither the quantized image.  The basic strategy of dithering is to
  2056. %      trade intensity resolution for spatial resolution by averaging the
  2057. %      intensities of several neighboring pixels.  Images which suffer
  2058. %      from severe contouring when quantized can be improved with the
  2059. %      technique of dithering.  Severe contouring generally occurs when
  2060. %      quantizing to very few colors, or to a poorly-chosen colormap.
  2061. %      Note, dithering is a computationally expensive process and will
  2062. %      increase processing time significantly.
  2063. %
  2064. %    o optimal: An unsigned integer value greater than zero indicates that
  2065. %      the optimal representation of the reference image should be returned.
  2066. %
  2067. %
  2068. */
  2069. void QuantizeImage(image,number_colors,tree_depth,dither,optimal)
  2070. Image
  2071. X  *image;
  2072. X
  2073. unsigned int
  2074. X  number_colors,
  2075. X  tree_depth,
  2076. X  dither,
  2077. X  optimal;
  2078. {
  2079. X  extern unsigned int
  2080. X    Quantize();
  2081. X
  2082. X  /*
  2083. X    Allocate quantized colormap.
  2084. X  */
  2085. X  if (number_colors > MaxColormapSize)
  2086. X    number_colors=MaxColormapSize;
  2087. X  if (image->colormap != (ColorPacket *) NULL)
  2088. X    (void) free((char *) image->colormap);
  2089. X  image->colormap=(ColorPacket *) malloc(number_colors*sizeof(ColorPacket));
  2090. X  if (image->colormap == (ColorPacket *) NULL)
  2091. X    {
  2092. X      Warning("unable to quantize image","memory allocation failed");
  2093. X      exit(1);
  2094. X    }
  2095. X  /*
  2096. X    Reduce the number of colors in the continuous tone image.
  2097. X  */
  2098. X  image->colors=Quantize(image,number_colors,tree_depth,dither,optimal);
  2099. X  image->class=PseudoClass;
  2100. }
  2101. SHAR_EOF
  2102. chmod 0755 ImageMagick/quantize.c ||
  2103. echo 'restore of ImageMagick/quantize.c failed'
  2104. Wc_c="`wc -c < 'ImageMagick/quantize.c'`"
  2105. test 20010 -eq "$Wc_c" ||
  2106.     echo 'ImageMagick/quantize.c: original size 20010, current size' "$Wc_c"
  2107. rm -f _shar_wnt_.tmp
  2108. fi
  2109. # ============= ImageMagick/rotate.c ==============
  2110. if test -f 'ImageMagick/rotate.c' -a X"$1" != X"-c"; then
  2111.     echo 'x - skipping ImageMagick/rotate.c (File already exists)'
  2112.     rm -f _shar_wnt_.tmp
  2113. else
  2114. > _shar_wnt_.tmp
  2115. echo 'x - extracting ImageMagick/rotate.c (Text)'
  2116. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/rotate.c' &&
  2117. /*
  2118. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2119. %                                                                             %
  2120. %                                                                             %
  2121. SHAR_EOF
  2122. true || echo 'restore of ImageMagick/rotate.c failed'
  2123. fi
  2124. echo 'End of ImageMagick part 10'
  2125. echo 'File ImageMagick/rotate.c is continued in part 11'
  2126. echo 11 > _shar_seq_.tmp
  2127. exit 0
  2128. --
  2129. Dan Heller
  2130. O'Reilly && Associates       Z-Code Software    Comp-sources-x:
  2131. Senior Writer                President          comp-sources-x@uunet.uu.net
  2132. argv@ora.com                 argv@zipcode.com
  2133.