4141#define FLOOR (v ) ((v) >= 0.0 ? (int)(v) : (int)floor(v))
4242
4343#define INK8 (ink ) (*(UINT8 *)ink)
44- #define INK16 (ink ) (*(UINT16 *)ink)
44+
45+ // True when the given I;16 mode stores its pixels most significant byte first.
46+ static inline int
47+ isModeI16BigEndian (const ModeID mode ) {
48+ #ifdef WORDS_BIGENDIAN
49+ return mode == IMAGING_MODE_I_16B || mode == IMAGING_MODE_I_16N ;
50+ #else
51+ return mode == IMAGING_MODE_I_16B ;
52+ #endif
53+ }
54+
55+ // Convert getink()'s ink value into the image's storage order
56+ // and return in the native order so the drawing functions don't
57+ // need to care about it.
58+ static inline INT32
59+ ink16 (Imaging im , const void * ink_ ) {
60+ const UINT8 * in = ink_ ;
61+ UINT8 out [2 ];
62+ UINT16 ink ;
63+
64+ if (isModeI16BigEndian (im -> mode )) {
65+ out [0 ] = in [1 ];
66+ out [1 ] = in [0 ];
67+ } else {
68+ out [0 ] = in [0 ];
69+ out [1 ] = in [1 ];
70+ }
71+ memcpy (& ink , out , sizeof (ink ));
72+ return ink ;
73+ }
4574
4675/*
4776 * Rounds around zero (up=away from zero, down=towards zero)
@@ -68,17 +97,14 @@ typedef void (*hline_handler)(Imaging, int, int, int, int, Imaging);
6897static inline void
6998point8 (Imaging im , int x , int y , int ink ) {
7099 if (x >= 0 && x < im -> xsize && y >= 0 && y < im -> ysize ) {
71- if (isModeI16 (im -> mode )) {
72- #ifdef WORDS_BIGENDIAN
73- im -> image8 [y ][x * 2 ] = (UINT8 )(ink >> 8 );
74- im -> image8 [y ][x * 2 + 1 ] = (UINT8 )ink ;
75- #else
76- im -> image8 [y ][x * 2 ] = (UINT8 )ink ;
77- im -> image8 [y ][x * 2 + 1 ] = (UINT8 )(ink >> 8 );
78- #endif
79- } else {
80- im -> image8 [y ][x ] = (UINT8 )ink ;
81- }
100+ im -> image8 [y ][x ] = (UINT8 )ink ;
101+ }
102+ }
103+
104+ static inline void
105+ point16 (Imaging im , int x , int y , int ink ) {
106+ if (x >= 0 && x < im -> xsize && y >= 0 && y < im -> ysize ) {
107+ ((UINT16 * )im -> image8 [y ])[x ] = (UINT16 )ink ;
82108 }
83109}
84110
@@ -116,33 +142,46 @@ hline8(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
116142 x1 = im -> xsize - 1 ;
117143 }
118144 if (x0 <= x1 ) {
119- int bigendian = -1 ;
120- if (isModeI16 (im -> mode )) {
121- bigendian =
122- (
123- #ifdef WORDS_BIGENDIAN
124- im -> mode == IMAGING_MODE_I_16 || im -> mode == IMAGING_MODE_I_16L
125- #else
126- im -> mode == IMAGING_MODE_I_16B
127- #endif
128- )
129- ? 1
130- : 0 ;
145+ UINT8 * p = im -> image8 [y0 ];
146+ if (mask == NULL ) {
147+ memset (p + x0 , (UINT8 )ink , (x1 - x0 + 1 ));
148+ } else {
149+ UINT8 * mask_row = mask -> image8 [y0 ];
150+ for (; x0 <= x1 ; x0 ++ ) {
151+ if (mask_row [x0 ]) {
152+ p [x0 ] = (UINT8 )ink ;
153+ }
154+ }
131155 }
132- if (mask == NULL && bigendian == -1 ) {
133- memset (im -> image8 [y0 ] + x0 , (UINT8 )ink , (x1 - x0 + 1 ));
156+ }
157+ }
158+ }
159+
160+ static inline void
161+ hline16 (Imaging im , int x0 , int y0 , int x1 , int ink , Imaging mask ) {
162+ if (y0 >= 0 && y0 < im -> ysize ) {
163+ if (x0 < 0 ) {
164+ x0 = 0 ;
165+ } else if (x0 >= im -> xsize ) {
166+ return ;
167+ }
168+ if (x1 < 0 ) {
169+ return ;
170+ } else if (x1 >= im -> xsize ) {
171+ x1 = im -> xsize - 1 ;
172+ }
173+ if (x0 <= x1 ) {
174+ UINT16 * p = (UINT16 * )im -> image8 [y0 ];
175+ if (mask == NULL ) {
176+ for (; x0 <= x1 ; x0 ++ ) {
177+ p [x0 ] = (UINT16 )ink ;
178+ }
134179 } else {
135- UINT8 * p = im -> image8 [y0 ];
136- while (x0 <= x1 ) {
137- if (mask == NULL || mask -> image8 [y0 ][x0 ]) {
138- if (bigendian == -1 ) {
139- p [x0 ] = ink ;
140- } else {
141- p [x0 * 2 + (bigendian ? 1 : 0 )] = ink ;
142- p [x0 * 2 + (bigendian ? 0 : 1 )] = ink >> 8 ;
143- }
180+ UINT8 * mask_row = mask -> image8 [y0 ];
181+ for (; x0 <= x1 ; x0 ++ ) {
182+ if (mask_row [x0 ]) {
183+ p [x0 ] = (UINT16 )ink ;
144184 }
145- x0 ++ ;
146185 }
147186 }
148187 }
@@ -275,6 +314,11 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
275314 GEN_LINE (point8 , hline8 );
276315}
277316
317+ static inline void
318+ line16 (Imaging im , int x0 , int y0 , int x1 , int y1 , int ink ) {
319+ GEN_LINE (point16 , hline16 );
320+ }
321+
278322static inline void
279323line32 (Imaging im , int x0 , int y0 , int x1 , int y1 , int ink ) {
280324 GEN_LINE (point32 , hline32 );
@@ -533,6 +577,7 @@ typedef struct {
533577} DRAW ;
534578
535579DRAW draw8 = {point8 , hline8 , line8 };
580+ DRAW draw16 = {point16 , hline16 , line16 };
536581DRAW draw32 = {point32 , hline32 , line32 };
537582DRAW draw32rgba = {point32rgba , hline32rgba , line32rgba };
538583
@@ -542,10 +587,11 @@ DRAW draw32rgba = {point32rgba, hline32rgba, line32rgba};
542587
543588#define DRAWINIT () \
544589 if (im->image8) { \
545- draw = &draw8; \
546590 if (isModeI16(im->mode)) { \
547- ink = INK16(ink_); \
591+ draw = &draw16; \
592+ ink = ink16(im, ink_); \
548593 } else { \
594+ draw = &draw8; \
549595 ink = INK8(ink_); \
550596 } \
551597 } else { \
0 commit comments