00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdio.h>
00026 #include <math.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <midas.h>
00030 #include "mgd.h"
00031
00032 int gdFontGiantData[] = {
00033 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00034 0, 0, 0, 0, 0, 48, 120, 252, 510, 252, 120, 48, 0, 0, 0,
00035 0, 0, 0, 0, 0, 438, 204, 438, 204, 438, 204, 438, 0, 0, 0,
00036 0, 0, 0, 102, 102, 126, 102, 102, 0, 504, 96, 96, 96, 96, 0,
00037 0, 0, 0, 62, 6, 30, 6, 6, 0, 496, 48, 240, 48, 48, 0,
00038 0, 0, 0, 124, 70, 6, 70, 124, 0, 248, 408, 248, 408, 408, 0,
00039 0, 0, 0, 6, 6, 6, 6, 62, 0, 496, 48, 240, 48, 48, 0,
00040 0, 0, 0, 0, 0, 120, 204, 204, 120, 0, 0, 0, 0, 0, 0,
00041 0, 0, 48, 48, 48, 510, 510, 48, 48, 48, 0, 510, 510, 0, 0,
00042 0, 0, 0, 102, 110, 126, 118, 102, 0, 48, 48, 48, 48, 496, 0,
00043 0, 0, 0, 102, 102, 102, 60, 24, 0, 504, 96, 96, 96, 96, 0,
00044 48, 48, 48, 48, 48, 48, 48, 63, 63, 0, 0, 0, 0, 0, 0,
00045 0, 0, 0, 0, 0, 0, 0, 63, 63, 48, 48, 48, 48, 48, 48,
00046 0, 0, 0, 0, 0, 0, 0, 496, 496, 48, 48, 48, 48, 48, 48,
00047 48, 48, 48, 48, 48, 48, 48, 496, 496, 0, 0, 0, 0, 0, 0,
00048 48, 48, 48, 48, 48, 48, 48, 511, 511, 48, 48, 48, 48, 48, 48,
00049 0, 0, 0, 511, 511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00050 0, 0, 0, 0, 0, 511, 511, 0, 0, 0, 0, 0, 0, 0, 0,
00051 0, 0, 0, 0, 0, 0, 0, 511, 511, 0, 0, 0, 0, 0, 0,
00052 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, 511, 0, 0, 0, 0,
00053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, 511, 0, 0,
00054 48, 48, 48, 48, 48, 48, 48, 496, 496, 48, 48, 48, 48, 48, 48,
00055 48, 48, 48, 48, 48, 48, 48, 63, 63, 48, 48, 48, 48, 48, 48,
00056 48, 48, 48, 48, 48, 48, 48, 511, 511, 0, 0, 0, 0, 0, 0,
00057 0, 0, 0, 0, 0, 0, 0, 511, 511, 48, 48, 48, 48, 48, 48,
00058 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
00059 0, 0, 0, 448, 112, 28, 6, 28, 112, 448, 0, 510, 510, 0, 0,
00060 0, 0, 0, 14, 56, 224, 384, 224, 56, 14, 0, 510, 510, 0, 0,
00061 0, 0, 0, 0, 0, 510, 510, 200, 200, 200, 206, 206, 0, 0, 0,
00062 0, 0, 0, 384, 192, 510, 510, 48, 510, 510, 12, 6, 0, 0, 0,
00063 0, 0, 0, 240, 408, 24, 24, 252, 24, 24, 62, 506, 14, 0, 0,
00064 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 0, 0, 0, 0, 0,
00065 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00066 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 0, 0,
00067 0, 0, 216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00068 0, 0, 0, 108, 108, 254, 108, 108, 254, 108, 108, 0, 0, 0, 0,
00069 0, 0, 32, 248, 428, 44, 60, 248, 480, 416, 428, 248, 32, 0, 0,
00070 0, 0, 396, 222, 222, 108, 48, 48, 216, 492, 492, 198, 0, 0, 0,
00071 0, 0, 60, 102, 102, 102, 60, 102, 486, 198, 230, 444, 0, 0, 0,
00072 0, 0, 240, 112, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00073 0, 96, 48, 24, 24, 12, 12, 12, 12, 24, 24, 48, 96, 0, 0,
00074 0, 12, 24, 48, 48, 96, 96, 96, 96, 48, 48, 24, 12, 0, 0,
00075 0, 0, 0, 16, 214, 124, 56, 238, 56, 124, 214, 16, 0, 0, 0,
00076 0, 0, 0, 0, 48, 48, 48, 510, 48, 48, 48, 0, 0, 0, 0,
00077 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 56, 12, 0, 0,
00078 0, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0,
00079 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 120, 48, 0, 0,
00080 0, 0, 384, 192, 192, 96, 48, 48, 24, 12, 12, 6, 0, 0, 0,
00081 0, 0, 120, 204, 390, 390, 390, 390, 390, 390, 204, 120, 0, 0, 0,
00082 0, 0, 48, 56, 60, 48, 48, 48, 48, 48, 48, 252, 0, 0, 0,
00083 0, 0, 252, 390, 390, 384, 192, 96, 56, 12, 6, 510, 0, 0, 0,
00084 0, 0, 510, 384, 192, 96, 240, 384, 384, 384, 390, 252, 0, 0, 0,
00085 0, 0, 192, 224, 240, 216, 204, 198, 510, 192, 192, 192, 0, 0, 0,
00086 0, 0, 510, 6, 6, 254, 398, 384, 384, 384, 390, 252, 0, 0, 0,
00087 0, 0, 248, 12, 6, 6, 254, 398, 390, 390, 390, 252, 0, 0, 0,
00088 0, 0, 510, 384, 384, 192, 96, 48, 24, 24, 12, 12, 0, 0, 0,
00089 0, 0, 252, 390, 390, 390, 252, 390, 390, 390, 390, 252, 0, 0, 0,
00090 0, 0, 252, 390, 390, 390, 454, 508, 384, 384, 192, 124, 0, 0, 0,
00091 0, 0, 0, 0, 0, 48, 120, 48, 0, 0, 48, 120, 48, 0, 0,
00092 0, 0, 0, 0, 0, 48, 120, 48, 0, 0, 120, 56, 12, 0, 0,
00093 0, 0, 192, 96, 48, 24, 12, 12, 24, 48, 96, 192, 0, 0, 0,
00094 0, 0, 0, 0, 0, 0, 510, 0, 0, 510, 0, 0, 0, 0, 0,
00095 0, 0, 12, 24, 48, 96, 192, 192, 96, 48, 24, 12, 0, 0, 0,
00096 0, 0, 252, 390, 390, 384, 192, 96, 48, 48, 0, 48, 0, 0, 0,
00097 0, 0, 252, 390, 390, 502, 414, 478, 502, 6, 6, 252, 0, 0, 0,
00098 0, 0, 48, 120, 204, 390, 390, 390, 510, 390, 390, 390, 0, 0, 0,
00099 0, 0, 254, 396, 396, 396, 252, 396, 396, 396, 396, 254, 0, 0, 0,
00100 0, 0, 252, 390, 6, 6, 6, 6, 6, 6, 390, 252, 0, 0, 0,
00101 0, 0, 254, 396, 396, 396, 396, 396, 396, 396, 396, 254, 0, 0, 0,
00102 0, 0, 510, 12, 12, 12, 124, 12, 12, 12, 12, 510, 0, 0, 0,
00103 0, 0, 510, 12, 12, 12, 124, 12, 12, 12, 12, 12, 0, 0, 0,
00104 0, 0, 252, 390, 6, 6, 6, 486, 390, 390, 390, 252, 0, 0, 0,
00105 0, 0, 390, 390, 390, 390, 510, 390, 390, 390, 390, 390, 0, 0, 0,
00106 0, 0, 252, 48, 48, 48, 48, 48, 48, 48, 48, 252, 0, 0, 0,
00107 0, 0, 496, 192, 192, 192, 192, 192, 192, 192, 198, 124, 0, 0, 0,
00108 0, 0, 390, 198, 102, 54, 30, 30, 54, 102, 198, 390, 0, 0, 0,
00109 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 510, 0, 0, 0,
00110 0, 0, 390, 390, 462, 510, 510, 438, 438, 390, 390, 390, 0, 0, 0,
00111 0, 0, 390, 390, 398, 414, 438, 486, 454, 390, 390, 390, 0, 0, 0,
00112 0, 0, 252, 390, 390, 390, 390, 390, 390, 390, 390, 252, 0, 0, 0,
00113 0, 0, 254, 390, 390, 390, 254, 6, 6, 6, 6, 6, 0, 0, 0,
00114 0, 0, 252, 390, 390, 390, 390, 390, 390, 438, 486, 252, 384, 0, 0,
00115 0, 0, 254, 390, 390, 390, 254, 54, 102, 198, 390, 390, 0, 0, 0,
00116 0, 0, 252, 390, 6, 6, 252, 384, 384, 384, 390, 252, 0, 0, 0,
00117 0, 0, 510, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0,
00118 0, 0, 390, 390, 390, 390, 390, 390, 390, 390, 390, 252, 0, 0, 0,
00119 0, 0, 390, 390, 390, 204, 204, 204, 120, 120, 120, 48, 0, 0, 0,
00120 0, 0, 390, 390, 390, 390, 438, 438, 438, 438, 510, 204, 0, 0, 0,
00121 0, 0, 390, 390, 204, 120, 48, 48, 120, 204, 390, 390, 0, 0, 0,
00122 0, 0, 390, 390, 204, 120, 48, 48, 48, 48, 48, 48, 0, 0, 0,
00123 0, 0, 510, 384, 192, 96, 48, 24, 12, 6, 6, 510, 0, 0, 0,
00124 0, 0, 248, 24, 24, 24, 24, 24, 24, 24, 24, 248, 0, 0, 0,
00125 0, 0, 6, 12, 12, 24, 48, 48, 96, 192, 192, 384, 0, 0, 0,
00126 0, 0, 124, 96, 96, 96, 96, 96, 96, 96, 96, 124, 0, 0, 0,
00127 0, 0, 48, 120, 204, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, 0, 0,
00129 0, 0, 60, 56, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00130 0, 0, 0, 0, 0, 252, 384, 384, 508, 390, 454, 508, 0, 0, 0,
00131 0, 0, 6, 6, 6, 254, 398, 390, 390, 390, 398, 254, 0, 0, 0,
00132 0, 0, 0, 0, 0, 252, 390, 6, 6, 6, 390, 252, 0, 0, 0,
00133 0, 0, 384, 384, 384, 508, 454, 390, 390, 390, 454, 508, 0, 0, 0,
00134 0, 0, 0, 0, 0, 252, 390, 390, 510, 6, 6, 252, 0, 0, 0,
00135 0, 0, 240, 408, 408, 24, 24, 126, 24, 24, 24, 24, 0, 0, 0,
00136 0, 0, 0, 0, 0, 508, 198, 198, 198, 124, 6, 252, 390, 390, 252,
00137 0, 0, 6, 6, 6, 254, 398, 390, 390, 390, 390, 390, 0, 0, 0,
00138 0, 0, 0, 48, 0, 56, 48, 48, 48, 48, 48, 252, 0, 0, 0,
00139 0, 0, 0, 192, 0, 240, 192, 192, 192, 192, 192, 198, 198, 198, 124,
00140 0, 0, 6, 6, 6, 390, 230, 62, 14, 62, 230, 390, 0, 0, 0,
00141 0, 0, 56, 48, 48, 48, 48, 48, 48, 48, 48, 252, 0, 0, 0,
00142 0, 0, 0, 0, 0, 254, 438, 438, 438, 438, 438, 390, 0, 0, 0,
00143 0, 0, 0, 0, 0, 254, 398, 390, 390, 390, 390, 390, 0, 0, 0,
00144 0, 0, 0, 0, 0, 252, 390, 390, 390, 390, 390, 252, 0, 0, 0,
00145 0, 0, 0, 0, 0, 254, 398, 390, 390, 390, 398, 254, 6, 6, 6,
00146 0, 0, 0, 0, 0, 508, 454, 390, 390, 390, 454, 508, 384, 384, 384,
00147 0, 0, 0, 0, 0, 246, 412, 396, 12, 12, 12, 12, 0, 0, 0,
00148 0, 0, 0, 0, 0, 252, 390, 6, 252, 384, 390, 252, 0, 0, 0,
00149 0, 0, 0, 24, 24, 254, 24, 24, 24, 24, 408, 240, 0, 0, 0,
00150 0, 0, 0, 0, 0, 198, 198, 198, 198, 198, 198, 508, 0, 0, 0,
00151 0, 0, 0, 0, 0, 390, 390, 204, 204, 120, 120, 48, 0, 0, 0,
00152 0, 0, 0, 0, 0, 390, 390, 438, 438, 438, 510, 204, 0, 0, 0,
00153 0, 0, 0, 0, 0, 390, 204, 120, 48, 120, 204, 390, 0, 0, 0,
00154 0, 0, 0, 0, 0, 198, 198, 198, 198, 198, 230, 252, 192, 198, 124,
00155 0, 0, 0, 0, 0, 510, 192, 96, 48, 24, 12, 510, 0, 0, 0,
00156 0, 0, 480, 48, 48, 96, 56, 56, 96, 48, 48, 480, 0, 0, 0,
00157 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0,
00158 0, 0, 30, 48, 48, 24, 112, 112, 24, 48, 48, 30, 0, 0, 0,
00159 0, 0, 412, 438, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00161 };
00162
00163 int gdFontMediumBoldData[] = {
00164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00165 0, 0, 0, 0, 0, 12, 30, 63, 30, 12, 0, 0, 0,
00166 0, 0, 0, 51, 51, 12, 51, 51, 12, 51, 51, 0, 0,
00167 0, 27, 27, 31, 27, 27, 0, 60, 24, 24, 24, 24, 0,
00168 0, 15, 3, 7, 3, 3, 0, 60, 12, 28, 12, 12, 0,
00169 0, 14, 3, 3, 3, 14, 0, 28, 44, 28, 44, 44, 0,
00170 0, 3, 3, 3, 3, 15, 0, 60, 12, 28, 12, 12, 0,
00171 0, 0, 30, 51, 51, 30, 0, 0, 0, 0, 0, 0, 0,
00172 0, 0, 12, 12, 63, 63, 12, 12, 0, 63, 63, 0, 0,
00173 0, 51, 55, 63, 59, 51, 0, 12, 12, 12, 12, 60, 0,
00174 0, 51, 51, 18, 30, 12, 0, 60, 24, 24, 24, 24, 0,
00175 12, 12, 12, 12, 12, 12, 15, 15, 0, 0, 0, 0, 0,
00176 0, 0, 0, 0, 0, 0, 15, 15, 12, 12, 12, 12, 12,
00177 0, 0, 0, 0, 0, 0, 124, 124, 12, 12, 12, 12, 12,
00178 12, 12, 12, 12, 12, 12, 124, 124, 0, 0, 0, 0, 0,
00179 12, 12, 12, 12, 12, 12, 127, 127, 12, 12, 12, 12, 12,
00180 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00181 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0,
00182 0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0,
00183 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0,
00184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0,
00185 12, 12, 12, 12, 12, 12, 124, 124, 12, 12, 12, 12, 12,
00186 12, 12, 12, 12, 12, 12, 15, 15, 12, 12, 12, 12, 12,
00187 12, 12, 12, 12, 12, 12, 127, 127, 0, 0, 0, 0, 0,
00188 0, 0, 0, 0, 0, 0, 127, 127, 12, 12, 12, 12, 12,
00189 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
00190 0, 0, 48, 24, 6, 3, 6, 24, 48, 63, 63, 0, 0,
00191 0, 0, 3, 6, 24, 48, 24, 6, 3, 63, 63, 0, 0,
00192 0, 0, 0, 0, 0, 63, 54, 54, 54, 55, 51, 0, 0,
00193 0, 0, 32, 48, 63, 63, 12, 63, 63, 3, 1, 0, 0,
00194 0, 0, 28, 54, 6, 6, 15, 6, 6, 54, 29, 0, 0,
00195 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0,
00196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00197 0, 0, 12, 12, 12, 12, 12, 12, 0, 12, 12, 0, 0,
00198 0, 0, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0,
00199 0, 0, 20, 20, 62, 62, 20, 62, 62, 20, 20, 0, 0,
00200 0, 0, 12, 30, 45, 13, 30, 44, 45, 30, 12, 0, 0,
00201 0, 0, 39, 53, 23, 24, 12, 6, 58, 43, 57, 0, 0,
00202 0, 0, 14, 27, 27, 27, 14, 43, 59, 27, 46, 0, 0,
00203 0, 0, 28, 28, 12, 6, 0, 0, 0, 0, 0, 0, 0,
00204 0, 0, 24, 12, 12, 6, 6, 6, 12, 12, 24, 0, 0,
00205 0, 0, 6, 12, 12, 24, 24, 24, 12, 12, 6, 0, 0,
00206 0, 0, 0, 0, 18, 12, 63, 63, 12, 18, 0, 0, 0,
00207 0, 0, 0, 0, 12, 12, 63, 63, 12, 12, 0, 0, 0,
00208 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 12, 6, 0,
00209 0, 0, 0, 0, 0, 0, 63, 63, 0, 0, 0, 0, 0,
00210 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 30, 12, 0,
00211 0, 0, 48, 48, 24, 24, 12, 6, 6, 3, 3, 0, 0,
00212 0, 0, 12, 18, 51, 51, 51, 51, 51, 18, 12, 0, 0,
00213 0, 0, 12, 14, 13, 12, 12, 12, 12, 12, 63, 0, 0,
00214 0, 0, 30, 51, 51, 48, 28, 6, 3, 3, 63, 0, 0,
00215 0, 0, 30, 51, 48, 48, 28, 48, 48, 51, 30, 0, 0,
00216 0, 0, 48, 56, 60, 54, 51, 51, 63, 48, 48, 0, 0,
00217 0, 0, 63, 3, 3, 31, 51, 48, 48, 51, 30, 0, 0,
00218 0, 0, 30, 51, 3, 3, 31, 51, 51, 51, 30, 0, 0,
00219 0, 0, 63, 48, 48, 24, 24, 12, 12, 6, 6, 0, 0,
00220 0, 0, 30, 51, 51, 51, 30, 51, 51, 51, 30, 0, 0,
00221 0, 0, 30, 51, 51, 51, 62, 48, 48, 51, 30, 0, 0,
00222 0, 0, 0, 0, 12, 30, 12, 0, 0, 12, 30, 12, 0,
00223 0, 0, 0, 0, 12, 30, 12, 0, 28, 28, 12, 6, 0,
00224 0, 0, 48, 24, 12, 6, 3, 6, 12, 24, 48, 0, 0,
00225 0, 0, 0, 0, 63, 63, 0, 63, 63, 0, 0, 0, 0,
00226 0, 0, 3, 6, 12, 24, 48, 24, 12, 6, 3, 0, 0,
00227 0, 0, 30, 51, 51, 48, 28, 12, 0, 12, 12, 0, 0,
00228 0, 0, 30, 49, 49, 61, 53, 61, 1, 49, 30, 0, 0,
00229 0, 0, 30, 51, 51, 51, 63, 51, 51, 51, 51, 0, 0,
00230 0, 0, 31, 51, 51, 51, 31, 51, 51, 51, 31, 0, 0,
00231 0, 0, 30, 51, 3, 3, 3, 3, 3, 51, 30, 0, 0,
00232 0, 0, 31, 51, 51, 51, 51, 51, 51, 51, 31, 0, 0,
00233 0, 0, 63, 3, 3, 3, 31, 3, 3, 3, 63, 0, 0,
00234 0, 0, 63, 3, 3, 3, 31, 3, 3, 3, 3, 0, 0,
00235 0, 0, 30, 51, 3, 3, 59, 51, 51, 51, 62, 0, 0,
00236 0, 0, 51, 51, 51, 51, 63, 51, 51, 51, 51, 0, 0,
00237 0, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0,
00238 0, 0, 48, 48, 48, 48, 48, 48, 48, 51, 30, 0, 0,
00239 0, 0, 35, 51, 27, 15, 7, 15, 27, 51, 35, 0, 0,
00240 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 63, 0, 0,
00241 0, 0, 33, 51, 63, 63, 51, 51, 51, 51, 51, 0, 0,
00242 0, 0, 51, 51, 55, 55, 63, 59, 59, 51, 51, 0, 0,
00243 0, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0,
00244 0, 0, 31, 51, 51, 51, 31, 3, 3, 3, 3, 0, 0,
00245 0, 0, 30, 51, 51, 51, 51, 51, 55, 59, 30, 48, 0,
00246 0, 0, 31, 51, 51, 51, 31, 15, 27, 51, 35, 0, 0,
00247 0, 0, 30, 51, 3, 3, 30, 48, 48, 51, 30, 0, 0,
00248 0, 0, 63, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0,
00249 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0,
00250 0, 0, 51, 51, 51, 18, 18, 30, 12, 12, 12, 0, 0,
00251 0, 0, 51, 51, 51, 51, 51, 63, 63, 51, 33, 0, 0,
00252 0, 0, 33, 51, 18, 30, 12, 30, 18, 51, 33, 0, 0,
00253 0, 0, 51, 51, 30, 30, 12, 12, 12, 12, 12, 0, 0,
00254 0, 0, 63, 48, 48, 24, 12, 6, 3, 3, 63, 0, 0,
00255 0, 0, 30, 6, 6, 6, 6, 6, 6, 6, 30, 0, 0,
00256 0, 0, 3, 3, 6, 6, 12, 24, 24, 48, 48, 0, 0,
00257 0, 0, 30, 24, 24, 24, 24, 24, 24, 24, 30, 0, 0,
00258 0, 0, 12, 30, 51, 33, 0, 0, 0, 0, 0, 0, 0,
00259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63, 0,
00260 0, 0, 14, 14, 12, 24, 0, 0, 0, 0, 0, 0, 0,
00261 0, 0, 0, 0, 0, 30, 48, 62, 51, 51, 62, 0, 0,
00262 0, 0, 3, 3, 3, 31, 51, 51, 51, 51, 31, 0, 0,
00263 0, 0, 0, 0, 0, 30, 51, 3, 3, 51, 30, 0, 0,
00264 0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 62, 0, 0,
00265 0, 0, 0, 0, 0, 30, 51, 63, 3, 51, 30, 0, 0,
00266 0, 0, 28, 54, 6, 6, 15, 6, 6, 6, 6, 0, 0,
00267 0, 0, 0, 0, 0, 46, 51, 51, 30, 3, 30, 51, 30,
00268 0, 0, 3, 3, 3, 31, 51, 51, 51, 51, 51, 0, 0,
00269 0, 0, 12, 12, 0, 14, 12, 12, 12, 12, 63, 0, 0,
00270 0, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 51, 30,
00271 0, 0, 3, 3, 3, 51, 27, 15, 15, 27, 51, 0, 0,
00272 0, 0, 14, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0,
00273 0, 0, 0, 0, 0, 27, 63, 63, 51, 51, 51, 0, 0,
00274 0, 0, 0, 0, 0, 31, 51, 51, 51, 51, 51, 0, 0,
00275 0, 0, 0, 0, 0, 30, 51, 51, 51, 51, 30, 0, 0,
00276 0, 0, 0, 0, 0, 31, 51, 51, 51, 31, 3, 3, 3,
00277 0, 0, 0, 0, 0, 62, 51, 51, 51, 62, 48, 48, 48,
00278 0, 0, 0, 0, 0, 31, 51, 3, 3, 3, 3, 0, 0,
00279 0, 0, 0, 0, 0, 30, 51, 6, 24, 51, 30, 0, 0,
00280 0, 0, 0, 3, 3, 15, 3, 3, 3, 51, 30, 0, 0,
00281 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 62, 0, 0,
00282 0, 0, 0, 0, 0, 51, 51, 51, 30, 30, 12, 0, 0,
00283 0, 0, 0, 0, 0, 51, 51, 51, 63, 63, 18, 0, 0,
00284 0, 0, 0, 0, 0, 51, 51, 30, 30, 51, 51, 0, 0,
00285 0, 0, 0, 0, 0, 51, 51, 51, 51, 62, 48, 51, 30,
00286 0, 0, 0, 0, 0, 63, 48, 24, 6, 3, 63, 0, 0,
00287 0, 0, 28, 6, 6, 12, 6, 12, 6, 6, 28, 0, 0,
00288 0, 0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0,
00289 0, 0, 14, 24, 24, 12, 24, 12, 24, 24, 14, 0, 0,
00290 0, 0, 38, 63, 25, 0, 0, 0, 0, 0, 0, 0, 0,
00291 42, 20, 42, 20, 42, 20, 42, 20, 42, 20, 42, 20, 42,
00292 };
00293
00294 int gdFontSmallData[] = {
00295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00296 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 0, 0,
00297 0, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0,
00298 0, 0, 0, 10, 31, 10, 10, 31, 10, 0, 0, 0,
00299 0, 4, 14, 21, 5, 14, 20, 21, 14, 4, 0, 0,
00300 0, 0, 31, 19, 8, 4, 2, 25, 25, 0, 0, 0,
00301 0, 0, 2, 5, 5, 2, 21, 9, 22, 0, 0, 0,
00302 0, 6, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0,
00303 0, 0, 16, 8, 4, 4, 4, 8, 16, 0, 0, 0,
00304 0, 0, 1, 2, 4, 4, 4, 2, 1, 0, 0, 0,
00305 0, 0, 4, 21, 14, 4, 14, 21, 4, 0, 0, 0,
00306 0, 0, 0, 4, 4, 31, 4, 4, 0, 0, 0, 0,
00307 0, 0, 0, 0, 0, 0, 0, 6, 6, 3, 0, 0,
00308 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0,
00309 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0,
00310 0, 0, 0, 16, 8, 4, 2, 1, 0, 0, 0, 0,
00311 0, 0, 14, 17, 25, 21, 19, 17, 14, 0, 0, 0,
00312 0, 0, 4, 6, 4, 4, 4, 4, 14, 0, 0, 0,
00313 0, 0, 14, 17, 16, 8, 4, 2, 31, 0, 0, 0,
00314 0, 0, 14, 17, 16, 12, 16, 17, 14, 0, 0, 0,
00315 0, 0, 8, 12, 10, 9, 31, 8, 8, 0, 0, 0,
00316 0, 0, 31, 1, 15, 16, 16, 17, 14, 0, 0, 0,
00317 0, 0, 12, 2, 1, 15, 17, 17, 14, 0, 0, 0,
00318 0, 0, 31, 16, 8, 8, 4, 4, 4, 0, 0, 0,
00319 0, 0, 14, 17, 17, 14, 17, 17, 14, 0, 0, 0,
00320 0, 0, 14, 17, 17, 30, 16, 8, 6, 0, 0, 0,
00321 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0,
00322 0, 0, 0, 0, 6, 6, 0, 6, 6, 3, 0, 0,
00323 0, 0, 0, 8, 4, 2, 4, 8, 0, 0, 0, 0,
00324 0, 0, 0, 0, 31, 0, 31, 0, 0, 0, 0, 0,
00325 0, 0, 0, 2, 4, 8, 4, 2, 0, 0, 0, 0,
00326 0, 0, 14, 17, 8, 4, 4, 0, 4, 0, 0, 0,
00327 0, 0, 14, 17, 29, 21, 29, 1, 14, 0, 0, 0,
00328 0, 0, 14, 17, 17, 31, 17, 17, 17, 0, 0, 0,
00329 0, 0, 15, 17, 17, 15, 17, 17, 15, 0, 0, 0,
00330 0, 0, 14, 17, 1, 1, 1, 17, 14, 0, 0, 0,
00331 0, 0, 15, 18, 18, 18, 18, 18, 15, 0, 0, 0,
00332 0, 0, 31, 1, 1, 15, 1, 1, 31, 0, 0, 0,
00333 0, 0, 31, 1, 1, 15, 1, 1, 1, 0, 0, 0,
00334 0, 0, 14, 17, 1, 1, 25, 17, 14, 0, 0, 0,
00335 0, 0, 17, 17, 17, 31, 17, 17, 17, 0, 0, 0,
00336 0, 0, 14, 4, 4, 4, 4, 4, 14, 0, 0, 0,
00337 0, 0, 16, 16, 16, 16, 16, 17, 14, 0, 0, 0,
00338 0, 0, 17, 9, 5, 3, 5, 9, 17, 0, 0, 0,
00339 0, 0, 1, 1, 1, 1, 1, 1, 31, 0, 0, 0,
00340 0, 0, 17, 27, 21, 17, 17, 17, 17, 0, 0, 0,
00341 0, 0, 17, 17, 19, 21, 25, 17, 17, 0, 0, 0,
00342 0, 0, 14, 17, 17, 17, 17, 17, 14, 0, 0, 0,
00343 0, 0, 15, 17, 17, 15, 1, 1, 1, 0, 0, 0,
00344 0, 0, 14, 17, 17, 17, 21, 9, 22, 0, 0, 0,
00345 0, 0, 15, 17, 17, 15, 5, 9, 17, 0, 0, 0,
00346 0, 0, 14, 17, 1, 14, 16, 17, 14, 0, 0, 0,
00347 0, 0, 31, 4, 4, 4, 4, 4, 4, 0, 0, 0,
00348 0, 0, 17, 17, 17, 17, 17, 17, 14, 0, 0, 0,
00349 0, 0, 17, 17, 17, 17, 10, 10, 4, 0, 0, 0,
00350 0, 0, 17, 17, 17, 17, 21, 27, 17, 0, 0, 0,
00351 0, 0, 17, 17, 10, 4, 10, 17, 17, 0, 0, 0,
00352 0, 0, 17, 17, 10, 4, 4, 4, 4, 0, 0, 0,
00353 0, 0, 31, 16, 8, 31, 2, 1, 31, 0, 0, 0,
00354 0, 28, 4, 4, 4, 4, 4, 4, 4, 28, 0, 0,
00355 0, 0, 0, 1, 2, 4, 8, 16, 0, 0, 0, 0,
00356 0, 7, 4, 4, 4, 4, 4, 4, 4, 7, 0, 0,
00357 0, 4, 10, 17, 0, 0, 0, 0, 0, 0, 0, 0,
00358 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0,
00359 0, 12, 12, 24, 0, 0, 0, 0, 0, 0, 0, 0,
00360 0, 0, 0, 0, 14, 16, 30, 17, 30, 0, 0, 0,
00361 0, 0, 1, 1, 15, 17, 17, 17, 15, 0, 0, 0,
00362 0, 0, 0, 0, 14, 17, 1, 1, 30, 0, 0, 0,
00363 0, 0, 16, 16, 30, 17, 17, 17, 30, 0, 0, 0,
00364 0, 0, 0, 0, 14, 17, 15, 1, 14, 0, 0, 0,
00365 0, 0, 12, 18, 2, 7, 2, 2, 2, 0, 0, 0,
00366 0, 0, 0, 0, 14, 17, 17, 17, 30, 16, 14, 0,
00367 0, 0, 1, 1, 15, 17, 17, 17, 17, 0, 0, 0,
00368 0, 0, 0, 4, 0, 4, 4, 4, 4, 0, 0, 0,
00369 0, 0, 0, 16, 0, 16, 16, 16, 16, 17, 14, 0,
00370 0, 0, 1, 1, 17, 9, 7, 9, 17, 0, 0, 0,
00371 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0,
00372 0, 0, 0, 0, 11, 21, 21, 21, 21, 0, 0, 0,
00373 0, 0, 0, 0, 13, 19, 17, 17, 17, 0, 0, 0,
00374 0, 0, 0, 0, 14, 17, 17, 17, 14, 0, 0, 0,
00375 0, 0, 0, 0, 15, 17, 17, 17, 15, 1, 1, 0,
00376 0, 0, 0, 0, 14, 17, 17, 17, 30, 16, 16, 0,
00377 0, 0, 0, 0, 13, 19, 1, 1, 1, 0, 0, 0,
00378 0, 0, 0, 0, 30, 1, 14, 16, 15, 0, 0, 0,
00379 0, 0, 4, 4, 31, 4, 4, 4, 24, 0, 0, 0,
00380 0, 0, 0, 0, 17, 17, 17, 17, 14, 0, 0, 0,
00381 0, 0, 0, 0, 17, 17, 17, 10, 4, 0, 0, 0,
00382 0, 0, 0, 0, 17, 17, 21, 21, 10, 0, 0, 0,
00383 0, 0, 0, 0, 17, 10, 4, 10, 17, 0, 0, 0,
00384 0, 0, 0, 0, 17, 17, 17, 10, 4, 2, 1, 0,
00385 0, 0, 0, 0, 31, 8, 14, 2, 31, 0, 0, 0,
00386 0, 16, 8, 8, 8, 4, 8, 8, 8, 16, 0, 0,
00387 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0,
00388 0, 1, 2, 2, 2, 4, 2, 2, 2, 1, 0, 0,
00389 0, 22, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00390 0, 0, 1, 1, 15, 17, 17, 17, 15, 0, 0, 0,
00391 };
00392
00393 gdFont gdFontGiantRep = {
00394 128, 0, 9, 15,
00395 gdFontGiantData
00396 };
00397
00398 gdFont gdFontMediumBoldRep = {
00399 128, 0, 7, 13,
00400 gdFontMediumBoldData
00401 };
00402
00403 gdFont gdFontSmallRep = {
00404 96, 32, 6, 12,
00405 gdFontSmallData
00406 };
00407
00408 gdFontPtr gdFontMediumBold = &gdFontMediumBoldRep;
00409 gdFontPtr gdFontGiant = &gdFontGiantRep;
00410 gdFontPtr gdFontSmall = &gdFontSmallRep;
00411
00412
00413
00414 static void gdImageBrushApply(gdImagePtr im, int x, int y);
00415 static void gdImageTileApply(gdImagePtr im, int x, int y);
00416
00417 gdImagePtr gdImageCreate(int sx, int sy)
00418 {
00419 int i;
00420 gdImagePtr im;
00421 im = (gdImage *) M_MALLOC(sizeof(gdImage));
00422 im->pixels = (unsigned char **) M_MALLOC(sizeof(unsigned char *) * sx);
00423 im->polyInts = 0;
00424 im->polyAllocated = 0;
00425 im->brush = 0;
00426 im->tile = 0;
00427 im->style = 0;
00428 for (i = 0; (i < sx); i++) {
00429 im->pixels[i] = (unsigned char *) M_CALLOC(sy, sizeof(unsigned char));
00430 }
00431 im->sx = sx;
00432 im->sy = sy;
00433 im->colorsTotal = 0;
00434 im->transparent = (-1);
00435 im->interlace = 0;
00436 return im;
00437 }
00438
00439 void gdImageDestroy(gdImagePtr im)
00440 {
00441 int i;
00442 for (i = 0; (i < im->sx); i++) {
00443 M_FREE(im->pixels[i]);
00444 }
00445 M_FREE(im->pixels);
00446 if (im->polyInts) {
00447 M_FREE(im->polyInts);
00448 }
00449 if (im->style) {
00450 M_FREE(im->style);
00451 }
00452 M_FREE(im);
00453 }
00454
00455 int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
00456 {
00457 int i;
00458 long rd, gd, bd;
00459 int ct = (-1);
00460 long mindist = 0;
00461 for (i = 0; (i < (im->colorsTotal)); i++) {
00462 long dist;
00463 if (im->open[i]) {
00464 continue;
00465 }
00466 rd = (im->red[i] - r);
00467 gd = (im->green[i] - g);
00468 bd = (im->blue[i] - b);
00469 dist = rd * rd + gd * gd + bd * bd;
00470 if ((i == 0) || (dist < mindist)) {
00471 mindist = dist;
00472 ct = i;
00473 }
00474 }
00475 return ct;
00476 }
00477
00478 int gdImageColorExact(gdImagePtr im, int r, int g, int b)
00479 {
00480 int i;
00481 for (i = 0; (i < (im->colorsTotal)); i++) {
00482 if (im->open[i]) {
00483 continue;
00484 }
00485 if ((im->red[i] == r) && (im->green[i] == g) && (im->blue[i] == b)) {
00486 return i;
00487 }
00488 }
00489 return -1;
00490 }
00491
00492 int gdImageColorAllocate(gdImagePtr im, int r, int g, int b)
00493 {
00494 int i;
00495 int ct = (-1);
00496
00497
00498 for (i = 0; (i < (im->colorsTotal)); i++) {
00499 if (!im->open[i] &&
00500 im->red[i] == r &&
00501 im->green[i] == g &&
00502 im->blue[i] == b) {
00503 return i;
00504 }
00505 }
00506
00507 for (i = 0; (i < (im->colorsTotal)); i++) {
00508 if (im->open[i]) {
00509 ct = i;
00510 break;
00511 }
00512 }
00513 if (ct == (-1)) {
00514 ct = im->colorsTotal;
00515 if (ct == gdMaxColors) {
00516 return -1;
00517 }
00518 im->colorsTotal++;
00519 }
00520 im->red[ct] = r;
00521 im->green[ct] = g;
00522 im->blue[ct] = b;
00523 im->open[ct] = 0;
00524 return ct;
00525 }
00526
00527 void gdImageColorDeallocate(gdImagePtr im, int color)
00528 {
00529
00530 im->open[color] = 1;
00531 }
00532
00533 void gdImageColorTransparent(gdImagePtr im, int color)
00534 {
00535 im->transparent = color;
00536 }
00537
00538 void gdImageSetPixel(gdImagePtr im, int x, int y, int color)
00539 {
00540 int p;
00541 switch (color) {
00542 case gdStyled:
00543 if (!im->style) {
00544
00545 return;
00546 } else {
00547 p = im->style[im->stylePos++];
00548 }
00549 if (p != (gdTransparent)) {
00550 gdImageSetPixel(im, x, y, p);
00551 }
00552 im->stylePos = im->stylePos % im->styleLength;
00553 break;
00554 case gdStyledBrushed:
00555 if (!im->style) {
00556
00557 return;
00558 }
00559 p = im->style[im->stylePos++];
00560 if ((p != gdTransparent) && (p != 0)) {
00561 gdImageSetPixel(im, x, y, gdBrushed);
00562 }
00563 im->stylePos = im->stylePos % im->styleLength;
00564 break;
00565 case gdBrushed:
00566 gdImageBrushApply(im, x, y);
00567 break;
00568 case gdTiled:
00569 gdImageTileApply(im, x, y);
00570 break;
00571 default:
00572 if (gdImageBoundsSafe(im, x, y)) {
00573 im->pixels[x][y] = color;
00574 }
00575 break;
00576 }
00577 }
00578
00579 static void gdImageBrushApply(gdImagePtr im, int x, int y)
00580 {
00581 int lx, ly;
00582 int hy;
00583 int hx;
00584 int x1, y1, x2, y2;
00585 int srcx, srcy;
00586 if (!im->brush) {
00587 return;
00588 }
00589 hy = gdImageSY(im->brush) / 2;
00590 y1 = y - hy;
00591 y2 = y1 + gdImageSY(im->brush);
00592 hx = gdImageSX(im->brush) / 2;
00593 x1 = x - hx;
00594 x2 = x1 + gdImageSX(im->brush);
00595 srcy = 0;
00596 for (ly = y1; (ly < y2); ly++) {
00597 srcx = 0;
00598 for (lx = x1; (lx < x2); lx++) {
00599 int p;
00600 p = gdImageGetPixel(im->brush, srcx, srcy);
00601
00602 if (p != gdImageGetTransparent(im->brush)) {
00603 gdImageSetPixel(im, lx, ly, im->brushColorMap[p]);
00604 }
00605 srcx++;
00606 }
00607 srcy++;
00608 }
00609 }
00610
00611 static void gdImageTileApply(gdImagePtr im, int x, int y)
00612 {
00613 int srcx, srcy;
00614 int p;
00615 if (!im->tile) {
00616 return;
00617 }
00618 srcx = x % gdImageSX(im->tile);
00619 srcy = y % gdImageSY(im->tile);
00620 p = gdImageGetPixel(im->tile, srcx, srcy);
00621
00622 if (p != gdImageGetTransparent(im->tile)) {
00623 gdImageSetPixel(im, x, y, im->tileColorMap[p]);
00624 }
00625 }
00626
00627 int gdImageGetPixel(gdImagePtr im, int x, int y)
00628 {
00629 if (gdImageBoundsSafe(im, x, y)) {
00630 return im->pixels[x][y];
00631 } else {
00632 return 0;
00633 }
00634 }
00635
00636
00637
00638 void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
00639 {
00640 int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
00641 dx = abs(x2 - x1);
00642 dy = abs(y2 - y1);
00643 if (dy <= dx) {
00644 d = 2 * dy - dx;
00645 incr1 = 2 * dy;
00646 incr2 = 2 * (dy - dx);
00647 if (x1 > x2) {
00648 x = x2;
00649 y = y2;
00650 ydirflag = (-1);
00651 xend = x1;
00652 } else {
00653 x = x1;
00654 y = y1;
00655 ydirflag = 1;
00656 xend = x2;
00657 }
00658 gdImageSetPixel(im, x, y, color);
00659 if (((y2 - y1) * ydirflag) > 0) {
00660 while (x < xend) {
00661 x++;
00662 if (d < 0) {
00663 d += incr1;
00664 } else {
00665 y++;
00666 d += incr2;
00667 }
00668 gdImageSetPixel(im, x, y, color);
00669 }
00670 } else {
00671 while (x < xend) {
00672 x++;
00673 if (d < 0) {
00674 d += incr1;
00675 } else {
00676 y--;
00677 d += incr2;
00678 }
00679 gdImageSetPixel(im, x, y, color);
00680 }
00681 }
00682 } else {
00683 d = 2 * dx - dy;
00684 incr1 = 2 * dx;
00685 incr2 = 2 * (dx - dy);
00686 if (y1 > y2) {
00687 y = y2;
00688 x = x2;
00689 yend = y1;
00690 xdirflag = (-1);
00691 } else {
00692 y = y1;
00693 x = x1;
00694 yend = y2;
00695 xdirflag = 1;
00696 }
00697 gdImageSetPixel(im, x, y, color);
00698 if (((x2 - x1) * xdirflag) > 0) {
00699 while (y < yend) {
00700 y++;
00701 if (d < 0) {
00702 d += incr1;
00703 } else {
00704 x++;
00705 d += incr2;
00706 }
00707 gdImageSetPixel(im, x, y, color);
00708 }
00709 } else {
00710 while (y < yend) {
00711 y++;
00712 if (d < 0) {
00713 d += incr1;
00714 } else {
00715 x--;
00716 d += incr2;
00717 }
00718 gdImageSetPixel(im, x, y, color);
00719 }
00720 }
00721 }
00722 }
00723
00724
00725
00726 #define dashedSet \
00727 { \
00728 dashStep++; \
00729 if (dashStep == gdDashSize) { \
00730 dashStep = 0; \
00731 on = !on; \
00732 } \
00733 if (on) { \
00734 gdImageSetPixel(im, x, y, color); \
00735 } \
00736 }
00737
00738 void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
00739 {
00740 int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
00741 int dashStep = 0;
00742 int on = 1;
00743 dx = abs(x2 - x1);
00744 dy = abs(y2 - y1);
00745 if (dy <= dx) {
00746 d = 2 * dy - dx;
00747 incr1 = 2 * dy;
00748 incr2 = 2 * (dy - dx);
00749 if (x1 > x2) {
00750 x = x2;
00751 y = y2;
00752 ydirflag = (-1);
00753 xend = x1;
00754 } else {
00755 x = x1;
00756 y = y1;
00757 ydirflag = 1;
00758 xend = x2;
00759 }
00760 dashedSet;
00761 if (((y2 - y1) * ydirflag) > 0) {
00762 while (x < xend) {
00763 x++;
00764 if (d < 0) {
00765 d += incr1;
00766 } else {
00767 y++;
00768 d += incr2;
00769 }
00770 dashedSet;
00771 }
00772 } else {
00773 while (x < xend) {
00774 x++;
00775 if (d < 0) {
00776 d += incr1;
00777 } else {
00778 y--;
00779 d += incr2;
00780 }
00781 dashedSet;
00782 }
00783 }
00784 } else {
00785 d = 2 * dx - dy;
00786 incr1 = 2 * dx;
00787 incr2 = 2 * (dx - dy);
00788 if (y1 > y2) {
00789 y = y2;
00790 x = x2;
00791 yend = y1;
00792 xdirflag = (-1);
00793 } else {
00794 y = y1;
00795 x = x1;
00796 yend = y2;
00797 xdirflag = 1;
00798 }
00799 dashedSet;
00800 if (((x2 - x1) * xdirflag) > 0) {
00801 while (y < yend) {
00802 y++;
00803 if (d < 0) {
00804 d += incr1;
00805 } else {
00806 x++;
00807 d += incr2;
00808 }
00809 dashedSet;
00810 }
00811 } else {
00812 while (y < yend) {
00813 y++;
00814 if (d < 0) {
00815 d += incr1;
00816 } else {
00817 x--;
00818 d += incr2;
00819 }
00820 dashedSet;
00821 }
00822 }
00823 }
00824 }
00825
00826 int gdImageBoundsSafe(gdImagePtr im, int x, int y)
00827 {
00828 return (!(((y < 0) || (y >= im->sy)) || ((x < 0) || (x >= im->sx))));
00829 }
00830
00831 void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color)
00832 {
00833 int cx, cy;
00834 int px, py;
00835 int fline;
00836 cx = 0;
00837 cy = 0;
00838 if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
00839 return;
00840 }
00841 fline = (c - f->offset) * f->h;
00842 for (py = y; (py < (y + f->h)); py++) {
00843 for (px = x; (px < (x + f->w)); px++) {
00844 if (f->data[fline + cy] & (1 << cx)) {
00845 gdImageSetPixel(im, px, py, color);
00846 }
00847 cx++;
00848 }
00849 cx = 0;
00850 cy++;
00851 }
00852 }
00853
00854 void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, char c, int color)
00855 {
00856 int cx, cy;
00857 int px, py;
00858 int fline;
00859 cx = 0;
00860 cy = 0;
00861 if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
00862 return;
00863 }
00864 fline = (c - f->offset) * f->h;
00865 for (py = y; (py > (y - f->w)); py--) {
00866 for (px = x; (px < (x + f->h)); px++) {
00867 if (f->data[fline + cy] & (1 << cx)) {
00868 gdImageSetPixel(im, px, py, color);
00869 }
00870 cy++;
00871 }
00872 cy = 0;
00873 cx++;
00874 }
00875 }
00876
00877 void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, char *s, int color)
00878 {
00879 int i;
00880 int l;
00881 l = strlen(s);
00882 for (i = 0; (i < l); i++) {
00883 gdImageChar(im, f, x, y, s[i], color);
00884 x += f->w;
00885 }
00886 }
00887
00888 void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, char *s, int color)
00889 {
00890 int i;
00891 int l;
00892 l = strlen(s);
00893 for (i = 0; (i < l); i++) {
00894 gdImageCharUp(im, f, x, y, s[i], color);
00895 y -= f->w;
00896 }
00897 }
00898
00899 void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color)
00900 {
00901 int lastBorder;
00902
00903 int leftLimit, rightLimit;
00904 int i;
00905 leftLimit = (-1);
00906 if (border < 0) {
00907
00908 return;
00909 }
00910 for (i = x; (i >= 0); i--) {
00911 if (gdImageGetPixel(im, i, y) == border) {
00912 break;
00913 }
00914 gdImageSetPixel(im, i, y, color);
00915 leftLimit = i;
00916 }
00917 if (leftLimit == (-1)) {
00918 return;
00919 }
00920
00921 rightLimit = x;
00922 for (i = (x + 1); (i < im->sx); i++) {
00923 if (gdImageGetPixel(im, i, y) == border) {
00924 break;
00925 }
00926 gdImageSetPixel(im, i, y, color);
00927 rightLimit = i;
00928 }
00929
00930
00931 if (y > 0) {
00932 lastBorder = 1;
00933 for (i = leftLimit; (i <= rightLimit); i++) {
00934 int c;
00935 c = gdImageGetPixel(im, i, y - 1);
00936 if (lastBorder) {
00937 if ((c != border) && (c != color)) {
00938 gdImageFillToBorder(im, i, y - 1, border, color);
00939 lastBorder = 0;
00940 }
00941 } else if ((c == border) || (c == color)) {
00942 lastBorder = 1;
00943 }
00944 }
00945 }
00946
00947 if (y < ((im->sy) - 1)) {
00948 lastBorder = 1;
00949 for (i = leftLimit; (i <= rightLimit); i++) {
00950 int c;
00951 c = gdImageGetPixel(im, i, y + 1);
00952 if (lastBorder) {
00953 if ((c != border) && (c != color)) {
00954 gdImageFillToBorder(im, i, y + 1, border, color);
00955 lastBorder = 0;
00956 }
00957 } else if ((c == border) || (c == color)) {
00958 lastBorder = 1;
00959 }
00960 }
00961 }
00962 }
00963
00964 void gdImageFill(gdImagePtr im, int x, int y, int color)
00965 {
00966 int lastBorder;
00967 int old;
00968 int leftLimit, rightLimit;
00969 int i;
00970 old = gdImageGetPixel(im, x, y);
00971 if (color == gdTiled) {
00972
00973 int p, tileColor;
00974 int srcx, srcy;
00975 if (!im->tile) {
00976 return;
00977 }
00978
00979
00980 if (gdImageGetTransparent(im->tile) != (-1)) {
00981 return;
00982 }
00983 srcx = x % gdImageSX(im->tile);
00984 srcy = y % gdImageSY(im->tile);
00985 p = gdImageGetPixel(im->tile, srcx, srcy);
00986 tileColor = im->tileColorMap[p];
00987 if (old == tileColor) {
00988
00989 return;
00990 }
00991 } else {
00992 if (old == color) {
00993
00994 return;
00995 }
00996 }
00997
00998 leftLimit = (-1);
00999 for (i = x; (i >= 0); i--) {
01000 if (gdImageGetPixel(im, i, y) != old) {
01001 break;
01002 }
01003 gdImageSetPixel(im, i, y, color);
01004 leftLimit = i;
01005 }
01006 if (leftLimit == (-1)) {
01007 return;
01008 }
01009
01010 rightLimit = x;
01011 for (i = (x + 1); (i < im->sx); i++) {
01012 if (gdImageGetPixel(im, i, y) != old) {
01013 break;
01014 }
01015 gdImageSetPixel(im, i, y, color);
01016 rightLimit = i;
01017 }
01018
01019
01020 if (y > 0) {
01021 lastBorder = 1;
01022 for (i = leftLimit; (i <= rightLimit); i++) {
01023 int c;
01024 c = gdImageGetPixel(im, i, y - 1);
01025 if (lastBorder) {
01026 if (c == old) {
01027 gdImageFill(im, i, y - 1, color);
01028 lastBorder = 0;
01029 }
01030 } else if (c != old) {
01031 lastBorder = 1;
01032 }
01033 }
01034 }
01035
01036 if (y < ((im->sy) - 1)) {
01037 lastBorder = 1;
01038 for (i = leftLimit; (i <= rightLimit); i++) {
01039 int c;
01040 c = gdImageGetPixel(im, i, y + 1);
01041 if (lastBorder) {
01042 if (c == old) {
01043 gdImageFill(im, i, y + 1, color);
01044 lastBorder = 0;
01045 }
01046 } else if (c != old) {
01047 lastBorder = 1;
01048 }
01049 }
01050 }
01051 }
01052
01053 #ifdef TEST_CODE
01054 void gdImageDump(gdImagePtr im)
01055 {
01056 int i, j;
01057 for (i = 0; (i < im->sy); i++) {
01058 for (j = 0; (j < im->sx); j++) {
01059 printf("%d", im->pixels[j][i]);
01060 }
01061 printf("\n");
01062 }
01063 }
01064 #endif
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 typedef int code_int;
01091
01092 #ifdef SIGNED_COMPARE_SLOW
01093 typedef unsigned long int count_int;
01094 typedef unsigned short int count_short;
01095 #else
01096 typedef long int count_int;
01097 #endif
01098
01099 static int colorstobpp(int colors);
01100 static void BumpPixel(void);
01101 static int GIFNextPixel(gdImagePtr im);
01102 static void GIFEncode(gdGifBuffer * buffer, int GWidth, int GHeight, int GInterlace,
01103 int Background, int Transparent, int BitsPerPixel, int *Red,
01104 int *Green, int *Blue, gdImagePtr im);
01105 static void Putword(int w, gdGifBuffer * buffer);
01106 static void compress(int init_bits, gdGifBuffer * buffer, gdImagePtr im);
01107 static void output(code_int code);
01108 static void cl_block(void);
01109 static void cl_hash(register count_int hsize);
01110 static void char_init(void);
01111 static void char_out(int c);
01112 static void flush_char(void);
01113
01114 static void init_statics(void);
01115
01116 char gif_buffer[500000];
01117
01118 void gdImageGif(gdImagePtr im, gdGifBuffer * buffer)
01119 {
01120 int interlace, transparent, BitsPerPixel;
01121 interlace = im->interlace;
01122 transparent = im->transparent;
01123
01124
01125 buffer->size = 0;
01126 buffer->data = gif_buffer;
01127
01128 BitsPerPixel = colorstobpp(im->colorsTotal);
01129
01130 init_statics();
01131
01132 GIFEncode(buffer, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel,
01133 im->red, im->green, im->blue, im);
01134 }
01135
01136 static int colorstobpp(int colors)
01137 {
01138 int bpp = 0;
01139
01140 if (colors <= 2)
01141 bpp = 1;
01142 else if (colors <= 4)
01143 bpp = 2;
01144 else if (colors <= 8)
01145 bpp = 3;
01146 else if (colors <= 16)
01147 bpp = 4;
01148 else if (colors <= 32)
01149 bpp = 5;
01150 else if (colors <= 64)
01151 bpp = 6;
01152 else if (colors <= 128)
01153 bpp = 7;
01154 else if (colors <= 256)
01155 bpp = 8;
01156 return bpp;
01157 }
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168 #define TRUE 1
01169 #define FALSE 0
01170
01171 static int Width, Height;
01172 static int curx, cury;
01173 static long CountDown;
01174 static int Pass = 0;
01175 static int Interlace;
01176
01177
01178
01179
01180 static void BumpPixel(void)
01181 {
01182
01183
01184
01185 ++curx;
01186
01187
01188
01189
01190
01191
01192 if (curx == Width) {
01193 curx = 0;
01194
01195 if (!Interlace)
01196 ++cury;
01197 else {
01198 switch (Pass) {
01199
01200 case 0:
01201 cury += 8;
01202 if (cury >= Height) {
01203 ++Pass;
01204 cury = 4;
01205 }
01206 break;
01207
01208 case 1:
01209 cury += 8;
01210 if (cury >= Height) {
01211 ++Pass;
01212 cury = 2;
01213 }
01214 break;
01215
01216 case 2:
01217 cury += 4;
01218 if (cury >= Height) {
01219 ++Pass;
01220 cury = 1;
01221 }
01222 break;
01223
01224 case 3:
01225 cury += 2;
01226 break;
01227 }
01228 }
01229 }
01230 }
01231
01232
01233
01234
01235 static int GIFNextPixel(gdImagePtr im)
01236 {
01237 int r;
01238
01239 if (CountDown == 0)
01240 return EOF;
01241
01242 --CountDown;
01243
01244 r = gdImageGetPixel(im, curx, cury);
01245
01246 BumpPixel();
01247
01248 return r;
01249 }
01250
01251
01252
01253 void bputc(int c, gdGifBuffer * buffer)
01254 {
01255 buffer->data[buffer->size++] = (unsigned char) c;
01256 }
01257
01258 static void
01259 GIFEncode(gdGifBuffer * buffer, int GWidth, int GHeight, int GInterlace, int Background,
01260 int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue,
01261 gdImagePtr im)
01262 {
01263 int B;
01264 int RWidth, RHeight;
01265 int LeftOfs, TopOfs;
01266 int Resolution;
01267 int ColorMapSize;
01268 int InitCodeSize;
01269 int i;
01270
01271 Interlace = GInterlace;
01272
01273 ColorMapSize = 1 << BitsPerPixel;
01274
01275 RWidth = Width = GWidth;
01276 RHeight = Height = GHeight;
01277 LeftOfs = TopOfs = 0;
01278
01279 Resolution = BitsPerPixel;
01280
01281
01282
01283
01284 CountDown = (long) Width *(long) Height;
01285
01286
01287
01288
01289 Pass = 0;
01290
01291
01292
01293
01294 if (BitsPerPixel <= 1)
01295 InitCodeSize = 2;
01296 else
01297 InitCodeSize = BitsPerPixel;
01298
01299
01300
01301
01302 curx = cury = 0;
01303
01304
01305
01306
01307 memcpy(buffer->data + buffer->size, Transparent < 0 ? "GIF87a" : "GIF89a", 6);
01308 buffer->size += 6;
01309
01310
01311
01312
01313 Putword(RWidth, buffer);
01314 Putword(RHeight, buffer);
01315
01316
01317
01318
01319 B = 0x80;
01320
01321
01322
01323
01324 B |= (Resolution - 1) << 5;
01325
01326
01327
01328
01329 B |= (BitsPerPixel - 1);
01330
01331
01332
01333
01334 bputc(B, buffer);
01335
01336
01337
01338
01339 bputc(Background, buffer);
01340
01341
01342
01343
01344 bputc(0, buffer);
01345
01346
01347
01348
01349 for (i = 0; i < ColorMapSize; ++i) {
01350 bputc(Red[i], buffer);
01351 bputc(Green[i], buffer);
01352 bputc(Blue[i], buffer);
01353 }
01354
01355
01356
01357
01358 if (Transparent >= 0) {
01359 bputc('!', buffer);
01360 bputc(0xf9, buffer);
01361 bputc(4, buffer);
01362 bputc(1, buffer);
01363 bputc(0, buffer);
01364 bputc(0, buffer);
01365 bputc((unsigned char) Transparent, buffer);
01366 bputc(0, buffer);
01367 }
01368
01369
01370
01371
01372 bputc(',', buffer);
01373
01374
01375
01376
01377
01378 Putword(LeftOfs, buffer);
01379 Putword(TopOfs, buffer);
01380 Putword(Width, buffer);
01381 Putword(Height, buffer);
01382
01383
01384
01385
01386 if (Interlace)
01387 bputc(0x40, buffer);
01388 else
01389 bputc(0x00, buffer);
01390
01391
01392
01393
01394 bputc(InitCodeSize, buffer);
01395
01396
01397
01398
01399 compress(InitCodeSize + 1, buffer, im);
01400
01401
01402
01403
01404 bputc(0, buffer);
01405
01406
01407
01408
01409 bputc(';', buffer);
01410 }
01411
01412
01413
01414
01415 static void Putword(int w, gdGifBuffer * buffer)
01416 {
01417 buffer->data[buffer->size++] = (unsigned char) (w & 0xff);
01418 buffer->data[buffer->size++] = (unsigned char) ((w / 256) & 0xff);
01419 }
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 #define GIFBITS 12
01436
01437 #define HSIZE 5003
01438
01439 #ifdef NO_UCHAR
01440 typedef char char_type;
01441 #else
01442 typedef unsigned char char_type;
01443 #endif
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459 #include <ctype.h>
01460
01461 #define ARGVAL() (*++(*argv) || (--argc && *++argv))
01462
01463 static int n_bits;
01464 static int maxbits = GIFBITS;
01465 static code_int maxcode;
01466 static code_int maxmaxcode = (code_int) 1 << GIFBITS;
01467 #ifdef COMPATIBLE
01468 # define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1)
01469 #else
01470 # define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
01471 #endif
01472 static count_int htab[HSIZE];
01473 static unsigned short codetab[HSIZE];
01474 #define HashTabOf(i) htab[i]
01475 #define CodeTabOf(i) codetab[i]
01476
01477 static code_int hsize = HSIZE;
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488 #define tab_prefixof(i) CodeTabOf(i)
01489 #define tab_suffixof(i) ((char_type*)(htab))[i]
01490 #define de_stack ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
01491
01492 static code_int free_ent = 0;
01493
01494
01495
01496
01497
01498 static int clear_flg = 0;
01499
01500 static int offset;
01501 static long int in_count = 1;
01502 static long int out_count = 0;
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 static int g_init_bits;
01521 static gdGifBuffer *g_outbuffer;
01522
01523 static int ClearCode;
01524 static int EOFCode;
01525
01526 static void compress(int init_bits, gdGifBuffer * buffer, gdImagePtr im)
01527 {
01528 register long fcode;
01529 register code_int i ;
01530 register int c;
01531 register code_int ent;
01532 register code_int disp;
01533 register code_int hsize_reg;
01534 register int hshift;
01535
01536
01537
01538
01539
01540 g_init_bits = init_bits;
01541 g_outbuffer = buffer;
01542
01543
01544
01545
01546 offset = 0;
01547 out_count = 0;
01548 clear_flg = 0;
01549 in_count = 1;
01550 maxcode = MAXCODE(n_bits = g_init_bits);
01551
01552 ClearCode = (1 << (init_bits - 1));
01553 EOFCode = ClearCode + 1;
01554 free_ent = ClearCode + 2;
01555
01556 char_init();
01557
01558 ent = GIFNextPixel(im);
01559
01560 hshift = 0;
01561 for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
01562 ++hshift;
01563 hshift = 8 - hshift;
01564
01565 hsize_reg = hsize;
01566 cl_hash((count_int) hsize_reg);
01567
01568 output((code_int) ClearCode);
01569
01570 #ifdef SIGNED_COMPARE_SLOW
01571 while ((c = GIFNextPixel(im)) != (unsigned) EOF) {
01572 #else
01573 while ((c = GIFNextPixel(im)) != EOF) {
01574 #endif
01575
01576 ++in_count;
01577
01578 fcode = (long) (((long) c << maxbits) + ent);
01579 i = (((code_int) c << hshift) ^ ent);
01580
01581 if (HashTabOf(i) == fcode) {
01582 ent = CodeTabOf(i);
01583 continue;
01584 } else if ((long) HashTabOf(i) < 0)
01585 goto nomatch;
01586 disp = hsize_reg - i;
01587 if (i == 0)
01588 disp = 1;
01589 probe:
01590 if ((i -= disp) < 0)
01591 i += hsize_reg;
01592
01593 if (HashTabOf(i) == fcode) {
01594 ent = CodeTabOf(i);
01595 continue;
01596 }
01597 if ((long) HashTabOf(i) > 0)
01598 goto probe;
01599 nomatch:
01600 output((code_int) ent);
01601 ++out_count;
01602 ent = c;
01603 #ifdef SIGNED_COMPARE_SLOW
01604 if ((unsigned) free_ent < (unsigned) maxmaxcode) {
01605 #else
01606 if (free_ent < maxmaxcode) {
01607 #endif
01608 CodeTabOf(i) = free_ent++;
01609 HashTabOf(i) = fcode;
01610 } else
01611 cl_block();
01612 }
01613
01614
01615
01616 output((code_int) ent);
01617 ++out_count;
01618 output((code_int) EOFCode);
01619 }
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638 static unsigned long cur_accum = 0;
01639 static int cur_bits = 0;
01640
01641 static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
01642 0x001F, 0x003F, 0x007F, 0x00FF,
01643 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
01644 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
01645 };
01646
01647 static void output(code_int code)
01648 {
01649 cur_accum &= masks[cur_bits];
01650
01651 if (cur_bits > 0)
01652 cur_accum |= ((long) code << cur_bits);
01653 else
01654 cur_accum = code;
01655
01656 cur_bits += n_bits;
01657
01658 while (cur_bits >= 8) {
01659 char_out((unsigned int) (cur_accum & 0xff));
01660 cur_accum >>= 8;
01661 cur_bits -= 8;
01662 }
01663
01664
01665
01666
01667
01668 if (free_ent > maxcode || clear_flg) {
01669
01670 if (clear_flg) {
01671
01672 maxcode = MAXCODE(n_bits = g_init_bits);
01673 clear_flg = 0;
01674
01675 } else {
01676
01677 ++n_bits;
01678 if (n_bits == maxbits)
01679 maxcode = maxmaxcode;
01680 else
01681 maxcode = MAXCODE(n_bits);
01682 }
01683 }
01684
01685 if (code == EOFCode) {
01686
01687
01688
01689 while (cur_bits > 0) {
01690 char_out((unsigned int) (cur_accum & 0xff));
01691 cur_accum >>= 8;
01692 cur_bits -= 8;
01693 }
01694
01695 flush_char();
01696
01697 }
01698 }
01699
01700
01701
01702
01703 static void cl_block(void)
01704 {
01705
01706 cl_hash((count_int) hsize);
01707 free_ent = ClearCode + 2;
01708 clear_flg = 1;
01709
01710 output((code_int) ClearCode);
01711 }
01712
01713 static void cl_hash(register count_int hsize)
01714 {
01715
01716 register count_int *htab_p = htab + hsize;
01717
01718 register long i;
01719 register long m1 = -1;
01720
01721 i = hsize - 16;
01722 do {
01723 *(htab_p - 16) = m1;
01724 *(htab_p - 15) = m1;
01725 *(htab_p - 14) = m1;
01726 *(htab_p - 13) = m1;
01727 *(htab_p - 12) = m1;
01728 *(htab_p - 11) = m1;
01729 *(htab_p - 10) = m1;
01730 *(htab_p - 9) = m1;
01731 *(htab_p - 8) = m1;
01732 *(htab_p - 7) = m1;
01733 *(htab_p - 6) = m1;
01734 *(htab_p - 5) = m1;
01735 *(htab_p - 4) = m1;
01736 *(htab_p - 3) = m1;
01737 *(htab_p - 2) = m1;
01738 *(htab_p - 1) = m1;
01739 htab_p -= 16;
01740 } while ((i -= 16) >= 0);
01741
01742 for (i += 16; i > 0; --i)
01743 *--htab_p = m1;
01744 }
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755 static int a_count;
01756
01757
01758
01759
01760 static void char_init(void)
01761 {
01762 a_count = 0;
01763 }
01764
01765
01766
01767
01768 static char accum[256];
01769
01770
01771
01772
01773
01774 static void char_out(int c)
01775 {
01776 accum[a_count++] = c;
01777 if (a_count >= 254)
01778 flush_char();
01779 }
01780
01781
01782
01783
01784 static void flush_char(void)
01785 {
01786 if (a_count > 0) {
01787 bputc(a_count, g_outbuffer);
01788 memcpy(g_outbuffer->data + g_outbuffer->size, accum, a_count);
01789 g_outbuffer->size += a_count;
01790 a_count = 0;
01791 }
01792 }
01793
01794 static void init_statics(void)
01795 {
01796
01797
01798
01799
01800 Width = 0;
01801 Height = 0;
01802 curx = 0;
01803 cury = 0;
01804 CountDown = 0;
01805 Pass = 0;
01806 Interlace = 0;
01807 a_count = 0;
01808 cur_accum = 0;
01809 cur_bits = 0;
01810 g_init_bits = 0;
01811 g_outbuffer = 0;
01812 ClearCode = 0;
01813 EOFCode = 0;
01814 free_ent = 0;
01815 clear_flg = 0;
01816 offset = 0;
01817 in_count = 1;
01818 out_count = 0;
01819 hsize = HSIZE;
01820 n_bits = 0;
01821 maxbits = GIFBITS;
01822 maxcode = 0;
01823 maxmaxcode = (code_int) 1 << GIFBITS;
01824 }
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 #define MAXCOLORMAPSIZE 256
01839
01840 #define TRUE 1
01841 #define FALSE 0
01842
01843 #define CM_RED 0
01844 #define CM_GREEN 1
01845 #define CM_BLUE 2
01846
01847 #define MAX_LWZ_BITS 12
01848
01849 #define INTERLACE 0x40
01850 #define LOCALCOLORMAP 0x80
01851 #define BitSet(byte, bit) (((byte) & (bit)) == (bit))
01852
01853 #define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
01854
01855 #define LM_to_uint(a,b) (((b)<<8)|(a))
01856
01857
01858 #if 0
01859 static struct {
01860 unsigned int Width;
01861 unsigned int Height;
01862 unsigned char ColorMap[3][MAXCOLORMAPSIZE];
01863 unsigned int BitPixel;
01864 unsigned int ColorResolution;
01865 unsigned int Background;
01866 unsigned int AspectRatio;
01867 } GifScreen;
01868 #endif
01869
01870 static struct {
01871 int transparent;
01872 int delayTime;
01873 int inputFlag;
01874 int disposal;
01875 } Gif89 = {
01876 -1, -1, -1, 0};
01877
01878 static int ReadColorMap(FILE * fd, int number, unsigned char (*buffer)[256]);
01879 static int DoExtension(FILE * fd, int label, int *Transparent);
01880 static int GetDataBlock(FILE * fd, unsigned char *buf);
01881 static int GetCode(FILE * fd, int code_size, int flag);
01882 static int LWZReadByte(FILE * fd, int flag, int input_code_size);
01883 static void ReadImage(gdImagePtr im, FILE * fd, int len, int height,
01884 unsigned char (*cmap)[256], int interlace, int ignore);
01885
01886 int ZeroDataBlock;
01887
01888 gdImagePtr gdImageCreateFromGif(FILE * fd)
01889 {
01890 int imageNumber;
01891 int BitPixel;
01892 int ColorResolution;
01893 int Background;
01894 int AspectRatio;
01895 int Transparent = (-1);
01896 unsigned char buf[16];
01897 unsigned char c;
01898 unsigned char ColorMap[3][MAXCOLORMAPSIZE];
01899 unsigned char localColorMap[3][MAXCOLORMAPSIZE];
01900 int imw, imh;
01901 int useGlobalColormap;
01902 int bitPixel;
01903 int imageCount = 0;
01904 char version[4];
01905 gdImagePtr im = 0;
01906 ZeroDataBlock = FALSE;
01907
01908 imageNumber = 1;
01909 if (!ReadOK(fd, buf, 6)) {
01910 return 0;
01911 }
01912 if (strncmp((char *) buf, "GIF", 3) != 0) {
01913 return 0;
01914 }
01915 strncpy(version, (char *) buf + 3, 3);
01916 version[3] = '\0';
01917
01918 if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
01919 return 0;
01920 }
01921 if (!ReadOK(fd, buf, 7)) {
01922 return 0;
01923 }
01924 BitPixel = 2 << (buf[4] & 0x07);
01925 ColorResolution = (int) (((buf[4] & 0x70) >> 3) + 1);
01926 Background = buf[5];
01927 AspectRatio = buf[6];
01928
01929 if (BitSet(buf[4], LOCALCOLORMAP)) {
01930 if (ReadColorMap(fd, BitPixel, ColorMap)) {
01931 return 0;
01932 }
01933 }
01934 for (;;) {
01935 if (!ReadOK(fd, &c, 1)) {
01936 return 0;
01937 }
01938 if (c == ';') {
01939 int i;
01940 if (imageCount < imageNumber) {
01941 return 0;
01942 }
01943
01944 if (!im) {
01945 return 0;
01946 }
01947
01948
01949
01950 for (i = ((im->colorsTotal - 1)); (i >= 0); i--) {
01951 if (im->open[i]) {
01952 im->colorsTotal--;
01953 } else {
01954 break;
01955 }
01956 }
01957 return im;
01958 }
01959
01960 if (c == '!') {
01961 if (!ReadOK(fd, &c, 1)) {
01962 return 0;
01963 }
01964 DoExtension(fd, c, &Transparent);
01965 continue;
01966 }
01967
01968 if (c != ',') {
01969 continue;
01970 }
01971
01972 ++imageCount;
01973
01974 if (!ReadOK(fd, buf, 9)) {
01975 return 0;
01976 }
01977
01978 useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);
01979
01980 bitPixel = 1 << ((buf[8] & 0x07) + 1);
01981
01982 imw = LM_to_uint(buf[4], buf[5]);
01983 imh = LM_to_uint(buf[6], buf[7]);
01984 if (!(im = gdImageCreate(imw, imh))) {
01985 return 0;
01986 }
01987 im->interlace = BitSet(buf[8], INTERLACE);
01988 if (!useGlobalColormap) {
01989 if (ReadColorMap(fd, bitPixel, localColorMap)) {
01990 return 0;
01991 }
01992 ReadImage(im, fd, imw, imh, localColorMap,
01993 BitSet(buf[8], INTERLACE), imageCount != imageNumber);
01994 } else {
01995 ReadImage(im, fd, imw, imh,
01996 ColorMap, BitSet(buf[8], INTERLACE), imageCount != imageNumber);
01997 }
01998 if (Transparent != (-1)) {
01999 gdImageColorTransparent(im, Transparent);
02000 }
02001 }
02002 }
02003
02004 static int ReadColorMap(FILE * fd, int number, unsigned char (*buffer)[256])
02005 {
02006 int i;
02007 unsigned char rgb[3];
02008
02009
02010 for (i = 0; i < number; ++i) {
02011 if (!ReadOK(fd, rgb, sizeof(rgb))) {
02012 return TRUE;
02013 }
02014 buffer[CM_RED][i] = rgb[0];
02015 buffer[CM_GREEN][i] = rgb[1];
02016 buffer[CM_BLUE][i] = rgb[2];
02017 }
02018
02019
02020 return FALSE;
02021 }
02022
02023 static int DoExtension(FILE * fd, int label, int *Transparent)
02024 {
02025 static unsigned char buf[256];
02026
02027 switch (label) {
02028 case 0xf9:
02029 (void) GetDataBlock(fd, (unsigned char *) buf);
02030 Gif89.disposal = (buf[0] >> 2) & 0x7;
02031 Gif89.inputFlag = (buf[0] >> 1) & 0x1;
02032 Gif89.delayTime = LM_to_uint(buf[1], buf[2]);
02033 if ((buf[0] & 0x1) != 0)
02034 *Transparent = buf[3];
02035
02036 while (GetDataBlock(fd, (unsigned char *) buf) != 0);
02037 return FALSE;
02038 default:
02039 break;
02040 }
02041 while (GetDataBlock(fd, (unsigned char *) buf) != 0);
02042
02043 return FALSE;
02044 }
02045
02046 static int GetDataBlock(FILE * fd, unsigned char *buf)
02047 {
02048 unsigned char count;
02049
02050 if (!ReadOK(fd, &count, 1)) {
02051 return -1;
02052 }
02053
02054 ZeroDataBlock = count == 0;
02055
02056 if ((count != 0) && (!ReadOK(fd, buf, count))) {
02057 return -1;
02058 }
02059
02060 return count;
02061 }
02062
02063 static int GetCode(FILE * fd, int code_size, int flag)
02064 {
02065 static unsigned char buf[280];
02066 static int curbit, lastbit, done, last_byte;
02067 int i, j, ret;
02068 unsigned char count;
02069
02070 if (flag) {
02071 curbit = 0;
02072 lastbit = 0;
02073 done = FALSE;
02074 return 0;
02075 }
02076
02077 if ((curbit + code_size) >= lastbit) {
02078 if (done) {
02079 if (curbit >= lastbit) {
02080
02081 }
02082 return -1;
02083 }
02084 buf[0] = buf[last_byte - 2];
02085 buf[1] = buf[last_byte - 1];
02086
02087 if ((count = GetDataBlock(fd, &buf[2])) == 0)
02088 done = TRUE;
02089
02090 last_byte = 2 + count;
02091 curbit = (curbit - lastbit) + 16;
02092 lastbit = (2 + count) * 8;
02093 }
02094
02095 ret = 0;
02096 for (i = curbit, j = 0; j < code_size; ++i, ++j)
02097 ret |= ((buf[i / 8] & (1 << (i % 8))) != 0) << j;
02098
02099 curbit += code_size;
02100
02101 return ret;
02102 }
02103
02104 static int LWZReadByte(FILE * fd, int flag, int input_code_size)
02105 {
02106 static int fresh = FALSE;
02107 int code, incode;
02108 static int code_size, set_code_size;
02109 static int max_code, max_code_size;
02110 static int firstcode, oldcode;
02111 static int clear_code, end_code;
02112 static int table[2][(1 << MAX_LWZ_BITS)];
02113 static int stack[(1 << (MAX_LWZ_BITS)) * 2], *sp;
02114 register int i;
02115
02116 if (flag) {
02117 set_code_size = input_code_size;
02118 code_size = set_code_size + 1;
02119 clear_code = 1 << set_code_size;
02120 end_code = clear_code + 1;
02121 max_code_size = 2 * clear_code;
02122 max_code = clear_code + 2;
02123
02124 GetCode(fd, 0, TRUE);
02125
02126 fresh = TRUE;
02127
02128 for (i = 0; i < clear_code; ++i) {
02129 table[0][i] = 0;
02130 table[1][i] = i;
02131 }
02132 for (; i < (1 << MAX_LWZ_BITS); ++i)
02133 table[0][i] = table[1][0] = 0;
02134
02135 sp = stack;
02136
02137 return 0;
02138 } else if (fresh) {
02139 fresh = FALSE;
02140 do {
02141 firstcode = oldcode = GetCode(fd, code_size, FALSE);
02142 } while (firstcode == clear_code);
02143 return firstcode;
02144 }
02145
02146 if (sp > stack)
02147 return *--sp;
02148
02149 while ((code = GetCode(fd, code_size, FALSE)) >= 0) {
02150 if (code == clear_code) {
02151 for (i = 0; i < clear_code; ++i) {
02152 table[0][i] = 0;
02153 table[1][i] = i;
02154 }
02155 for (; i < (1 << MAX_LWZ_BITS); ++i)
02156 table[0][i] = table[1][i] = 0;
02157 code_size = set_code_size + 1;
02158 max_code_size = 2 * clear_code;
02159 max_code = clear_code + 2;
02160 sp = stack;
02161 firstcode = oldcode = GetCode(fd, code_size, FALSE);
02162 return firstcode;
02163 } else if (code == end_code) {
02164 int count;
02165 unsigned char buf[260];
02166
02167 if (ZeroDataBlock)
02168 return -2;
02169
02170 while ((count = GetDataBlock(fd, buf)) > 0);
02171
02172 if (count != 0)
02173 return -2;
02174 }
02175
02176 incode = code;
02177
02178 if (code >= max_code) {
02179 *sp++ = firstcode;
02180 code = oldcode;
02181 }
02182
02183 while (code >= clear_code) {
02184 *sp++ = table[1][code];
02185 if (code == table[0][code]) {
02186
02187 }
02188 code = table[0][code];
02189 }
02190
02191 *sp++ = firstcode = table[1][code];
02192
02193 if ((code = max_code) < (1 << MAX_LWZ_BITS)) {
02194 table[0][code] = oldcode;
02195 table[1][code] = firstcode;
02196 ++max_code;
02197 if ((max_code >= max_code_size) && (max_code_size < (1 << MAX_LWZ_BITS))) {
02198 max_code_size *= 2;
02199 ++code_size;
02200 }
02201 }
02202
02203 oldcode = incode;
02204
02205 if (sp > stack)
02206 return *--sp;
02207 }
02208 return code;
02209 }
02210
02211 static void
02212 ReadImage(gdImagePtr im, FILE * fd, int len, int height, unsigned char (*cmap)[256],
02213 int interlace, int ignore)
02214 {
02215 unsigned char c;
02216 int v;
02217 int xpos = 0, ypos = 0, pass = 0;
02218 int i;
02219
02220 for (i = 0; (i < gdMaxColors); i++) {
02221 im->red[i] = cmap[CM_RED][i];
02222 im->green[i] = cmap[CM_GREEN][i];
02223 im->blue[i] = cmap[CM_BLUE][i];
02224 im->open[i] = 1;
02225 }
02226
02227 im->colorsTotal = gdMaxColors;
02228
02229
02230
02231 if (!ReadOK(fd, &c, 1)) {
02232 return;
02233 }
02234 if (LWZReadByte(fd, TRUE, c) < 0) {
02235 return;
02236 }
02237
02238
02239
02240
02241 if (ignore) {
02242 while (LWZReadByte(fd, FALSE, c) >= 0);
02243 return;
02244 }
02245
02246 while ((v = LWZReadByte(fd, FALSE, c)) >= 0) {
02247
02248 if (im->open[v]) {
02249 im->open[v] = 0;
02250 }
02251 gdImageSetPixel(im, xpos, ypos, v);
02252 ++xpos;
02253 if (xpos == len) {
02254 xpos = 0;
02255 if (interlace) {
02256 switch (pass) {
02257 case 0:
02258 case 1:
02259 ypos += 8;
02260 break;
02261 case 2:
02262 ypos += 4;
02263 break;
02264 case 3:
02265 ypos += 2;
02266 break;
02267 }
02268
02269 if (ypos >= height) {
02270 ++pass;
02271 switch (pass) {
02272 case 1:
02273 ypos = 4;
02274 break;
02275 case 2:
02276 ypos = 2;
02277 break;
02278 case 3:
02279 ypos = 1;
02280 break;
02281 default:
02282 goto fini;
02283 }
02284 }
02285 } else {
02286 ++ypos;
02287 }
02288 }
02289 if (ypos >= height)
02290 break;
02291 }
02292
02293 fini:
02294 if (LWZReadByte(fd, FALSE, c) >= 0) {
02295
02296 }
02297 }
02298
02299 void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
02300 {
02301 gdImageLine(im, x1, y1, x2, y1, color);
02302 gdImageLine(im, x1, y2, x2, y2, color);
02303 gdImageLine(im, x1, y1, x1, y2, color);
02304 gdImageLine(im, x2, y1, x2, y2, color);
02305 }
02306
02307 void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
02308 {
02309 int x, y;
02310 for (y = y1; (y <= y2); y++) {
02311 for (x = x1; (x <= x2); x++) {
02312 gdImageSetPixel(im, x, y, color);
02313 }
02314 }
02315 }
02316
02317 void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY,
02318 int w, int h)
02319 {
02320 int c;
02321 int x, y;
02322 int tox, toy;
02323 int i;
02324 int colorMap[gdMaxColors];
02325 for (i = 0; (i < gdMaxColors); i++) {
02326 colorMap[i] = (-1);
02327 }
02328 toy = dstY;
02329 for (y = srcY; (y < (srcY + h)); y++) {
02330 tox = dstX;
02331 for (x = srcX; (x < (srcX + w)); x++) {
02332 int nc;
02333 c = gdImageGetPixel(src, x, y);
02334
02335 if (gdImageGetTransparent(src) == c) {
02336 tox++;
02337 continue;
02338 }
02339
02340 if (colorMap[c] == (-1)) {
02341
02342 if (dst == src) {
02343 nc = c;
02344 } else {
02345
02346 nc = gdImageColorExact(dst, src->red[c], src->green[c], src->blue[c]);
02347 }
02348 if (nc == (-1)) {
02349
02350 nc = gdImageColorAllocate(dst, src->red[c], src->green[c], src->blue[c]);
02351
02352
02353 if (nc == (-1)) {
02354 nc = gdImageColorClosest(dst, src->red[c], src->green[c], src->blue[c]);
02355 }
02356 }
02357 colorMap[c] = nc;
02358 }
02359 gdImageSetPixel(dst, tox, toy, colorMap[c]);
02360 tox++;
02361 }
02362 toy++;
02363 }
02364 }
02365
02366 void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
02367 int srcY, int dstW, int dstH, int srcW, int srcH)
02368 {
02369 int c;
02370 int x, y;
02371 int tox, toy;
02372 int ydest;
02373 int i;
02374 int colorMap[gdMaxColors];
02375
02376 int *stx;
02377 int *sty;
02378
02379
02380 double accum;
02381 stx = (int *) M_MALLOC(sizeof(int) * srcW);
02382 sty = (int *) M_MALLOC(sizeof(int) * srcH);
02383 accum = 0;
02384 for (i = 0; (i < srcW); i++) {
02385 int got;
02386 accum += (double) dstW / (double) srcW;
02387 got = (int) floor(accum);
02388 stx[i] = got;
02389 accum -= got;
02390 }
02391 accum = 0;
02392 for (i = 0; (i < srcH); i++) {
02393 int got;
02394 accum += (double) dstH / (double) srcH;
02395 got = (int) floor(accum);
02396 sty[i] = got;
02397 accum -= got;
02398 }
02399 for (i = 0; (i < gdMaxColors); i++) {
02400 colorMap[i] = (-1);
02401 }
02402 toy = dstY;
02403 for (y = srcY; (y < (srcY + srcH)); y++) {
02404 for (ydest = 0; (ydest < sty[y - srcY]); ydest++) {
02405 tox = dstX;
02406 for (x = srcX; (x < (srcX + srcW)); x++) {
02407 int nc;
02408 if (!stx[x - srcX]) {
02409 continue;
02410 }
02411 c = gdImageGetPixel(src, x, y);
02412
02413 if (gdImageGetTransparent(src) == c) {
02414 tox += stx[x - srcX];
02415 continue;
02416 }
02417
02418 if (colorMap[c] == (-1)) {
02419
02420 if (dst == src) {
02421 nc = c;
02422 } else {
02423
02424 nc = gdImageColorExact(dst, src->red[c], src->green[c], src->blue[c]);
02425 }
02426 if (nc == (-1)) {
02427
02428 nc = gdImageColorAllocate(dst,
02429 src->red[c], src->green[c], src->blue[c]);
02430
02431
02432 if (nc == (-1)) {
02433 nc = gdImageColorClosest(dst,
02434 src->red[c], src->green[c], src->blue[c]);
02435 }
02436 }
02437 colorMap[c] = nc;
02438 }
02439 for (i = 0; (i < stx[x - srcX]); i++) {
02440 gdImageSetPixel(dst, tox, toy, colorMap[c]);
02441 tox++;
02442 }
02443 }
02444 toy++;
02445 }
02446 }
02447 M_FREE(stx);
02448 M_FREE(sty);
02449 }
02450
02451 void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c)
02452 {
02453 int i;
02454 int lx, ly;
02455 if (!n) {
02456 return;
02457 }
02458 lx = p->x;
02459 ly = p->y;
02460 gdImageLine(im, lx, ly, p[n - 1].x, p[n - 1].y, c);
02461 for (i = 1; (i < n); i++) {
02462 p++;
02463 gdImageLine(im, lx, ly, p->x, p->y, c);
02464 lx = p->x;
02465 ly = p->y;
02466 }
02467 }
02468
02469 int gdCompareInt(const void *a, const void *b);
02470
02471 void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
02472 {
02473 int i;
02474 int y;
02475 int y1, y2;
02476 int ints;
02477 if (!n) {
02478 return;
02479 }
02480 if (!im->polyAllocated) {
02481 im->polyInts = (int *) M_MALLOC(sizeof(int) * n);
02482 im->polyAllocated = n;
02483 }
02484 if (im->polyAllocated < n) {
02485 while (im->polyAllocated < n) {
02486 im->polyAllocated *= 2;
02487 }
02488 im->polyInts = (int *) realloc(im->polyInts, sizeof(int) * im->polyAllocated);
02489 }
02490 y1 = p[0].y;
02491 y2 = p[0].y;
02492 for (i = 1; (i < n); i++) {
02493 if (p[i].y < y1) {
02494 y1 = p[i].y;
02495 }
02496 if (p[i].y > y2) {
02497 y2 = p[i].y;
02498 }
02499 }
02500 for (y = y1; (y <= y2); y++) {
02501 int interLast = 0;
02502 int dirLast = 0;
02503 int interFirst = 1;
02504 ints = 0;
02505 for (i = 0; (i <= n); i++) {
02506 int x1, x2;
02507 int y1, y2;
02508 int dir;
02509 int ind1, ind2;
02510 int lastInd1 = 0;
02511 if ((i == n) || (!i)) {
02512 ind1 = n - 1;
02513 ind2 = 0;
02514 } else {
02515 ind1 = i - 1;
02516 ind2 = i;
02517 }
02518 y1 = p[ind1].y;
02519 y2 = p[ind2].y;
02520 if (y1 < y2) {
02521 y1 = p[ind1].y;
02522 y2 = p[ind2].y;
02523 x1 = p[ind1].x;
02524 x2 = p[ind2].x;
02525 dir = -1;
02526 } else if (y1 > y2) {
02527 y2 = p[ind1].y;
02528 y1 = p[ind2].y;
02529 x2 = p[ind1].x;
02530 x1 = p[ind2].x;
02531 dir = 1;
02532 } else {
02533
02534 gdImageLine(im, p[ind1].x, y1, p[ind2].x, y1, c);
02535 continue;
02536 }
02537 if ((y >= y1) && (y <= y2)) {
02538 int inter = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
02539
02540
02541
02542
02543
02544
02545 if (!interFirst) {
02546 if ((p[ind1].y == p[lastInd1].y) && (p[ind1].x != p[lastInd1].x)) {
02547 if (dir == dirLast) {
02548 if (inter > interLast) {
02549
02550 im->polyInts[ints] = inter;
02551 } else {
02552
02553 }
02554 continue;
02555 }
02556 }
02557 if (inter == interLast) {
02558 if (dir == dirLast) {
02559 continue;
02560 }
02561 }
02562 }
02563 if (i > 0) {
02564 im->polyInts[ints++] = inter;
02565 }
02566 lastInd1 = i;
02567 dirLast = dir;
02568 interLast = inter;
02569 interFirst = 0;
02570 }
02571 }
02572 qsort(im->polyInts, ints, sizeof(int), gdCompareInt);
02573 for (i = 0; (i < (ints - 1)); i += 2) {
02574 gdImageLine(im, im->polyInts[i], y, im->polyInts[i + 1], y, c);
02575 }
02576 }
02577 }
02578
02579 int gdCompareInt(const void *a, const void *b)
02580 {
02581 return (*(const int *) a) - (*(const int *) b);
02582 }
02583
02584 void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels)
02585 {
02586 if (im->style) {
02587 M_FREE(im->style);
02588 }
02589 im->style = (int *)
02590 M_MALLOC(sizeof(int) * noOfPixels);
02591 memcpy(im->style, style, sizeof(int) * noOfPixels);
02592 im->styleLength = noOfPixels;
02593 im->stylePos = 0;
02594 }
02595
02596 void gdImageSetBrush(gdImagePtr im, gdImagePtr brush)
02597 {
02598 int i;
02599 im->brush = brush;
02600 for (i = 0; (i < gdImageColorsTotal(brush)); i++) {
02601 int index;
02602 index = gdImageColorExact(im,
02603 gdImageRed(brush, i),
02604 gdImageGreen(brush, i), gdImageBlue(brush, i));
02605 if (index == (-1)) {
02606 index = gdImageColorAllocate(im,
02607 gdImageRed(brush, i),
02608 gdImageGreen(brush, i), gdImageBlue(brush, i));
02609 if (index == (-1)) {
02610 index = gdImageColorClosest(im,
02611 gdImageRed(brush, i),
02612 gdImageGreen(brush, i), gdImageBlue(brush, i));
02613 }
02614 }
02615 im->brushColorMap[i] = index;
02616 }
02617 }
02618
02619 void gdImageInterlace(gdImagePtr im, int interlaceArg)
02620 {
02621 im->interlace = interlaceArg;
02622 }