image.c revision a1287f549a3e6527b8cf3bf5b5f563ba63c6f48c
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.5
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27/**
28 * \file image.c
29 * Image handling.
30 */
31
32
33#include "glheader.h"
34#include "colormac.h"
35#include "glformats.h"
36#include "image.h"
37#include "imports.h"
38#include "macros.h"
39#include "mfeatures.h"
40#include "mtypes.h"
41
42
43
44/**
45 * Flip the order of the 2 bytes in each word in the given array.
46 *
47 * \param p array.
48 * \param n number of words.
49 */
50void
51_mesa_swap2( GLushort *p, GLuint n )
52{
53   GLuint i;
54   for (i = 0; i < n; i++) {
55      p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
56   }
57}
58
59
60
61/*
62 * Flip the order of the 4 bytes in each word in the given array.
63 */
64void
65_mesa_swap4( GLuint *p, GLuint n )
66{
67   GLuint i, a, b;
68   for (i = 0; i < n; i++) {
69      b = p[i];
70      a =  (b >> 24)
71	| ((b >> 8) & 0xff00)
72	| ((b << 8) & 0xff0000)
73	| ((b << 24) & 0xff000000);
74      p[i] = a;
75   }
76}
77
78
79/**
80 * Do error checking of format/type combinations for glReadPixels,
81 * glDrawPixels and glTex[Sub]Image.  Note that depending on the format
82 * and type values, we may either generate GL_INVALID_OPERATION or
83 * GL_INVALID_ENUM.
84 *
85 * \param format pixel format.
86 * \param type pixel type.
87 *
88 * \return GL_INVALID_ENUM, GL_INVALID_OPERATION or GL_NO_ERROR
89 */
90GLenum
91_mesa_error_check_format_and_type(const struct gl_context *ctx,
92                                  GLenum format, GLenum type)
93{
94   /* special type-based checks (see glReadPixels, glDrawPixels error lists) */
95   switch (type) {
96   case GL_BITMAP:
97      if (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX) {
98         return GL_INVALID_ENUM;
99      }
100      break;
101
102   case GL_UNSIGNED_BYTE_3_3_2:
103   case GL_UNSIGNED_BYTE_2_3_3_REV:
104   case GL_UNSIGNED_SHORT_5_6_5:
105   case GL_UNSIGNED_SHORT_5_6_5_REV:
106      if (format == GL_RGB) {
107         break; /* OK */
108      }
109      if (format == GL_RGB_INTEGER_EXT &&
110          ctx->Extensions.ARB_texture_rgb10_a2ui) {
111         break; /* OK */
112      }
113      return GL_INVALID_OPERATION;
114
115   case GL_UNSIGNED_SHORT_4_4_4_4:
116   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
117   case GL_UNSIGNED_SHORT_5_5_5_1:
118   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
119   case GL_UNSIGNED_INT_8_8_8_8:
120   case GL_UNSIGNED_INT_8_8_8_8_REV:
121   case GL_UNSIGNED_INT_10_10_10_2:
122   case GL_UNSIGNED_INT_2_10_10_10_REV:
123      if (format == GL_RGBA ||
124          format == GL_BGRA ||
125          format == GL_ABGR_EXT) {
126         break; /* OK */
127      }
128      if ((format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) &&
129          ctx->Extensions.ARB_texture_rgb10_a2ui) {
130         break; /* OK */
131      }
132      return GL_INVALID_OPERATION;
133
134   case GL_UNSIGNED_INT_24_8:
135      if (!ctx->Extensions.EXT_packed_depth_stencil) {
136         return GL_INVALID_ENUM;
137      }
138      if (format != GL_DEPTH_STENCIL) {
139         return GL_INVALID_OPERATION;
140      }
141      return GL_NO_ERROR;
142
143   case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
144      if (!ctx->Extensions.ARB_depth_buffer_float) {
145         return GL_INVALID_ENUM;
146      }
147      if (format != GL_DEPTH_STENCIL) {
148         return GL_INVALID_OPERATION;
149      }
150      return GL_NO_ERROR;
151
152   case GL_UNSIGNED_INT_10F_11F_11F_REV:
153      if (!ctx->Extensions.EXT_packed_float) {
154         return GL_INVALID_ENUM;
155      }
156      if (format != GL_RGB) {
157         return GL_INVALID_OPERATION;
158      }
159      return GL_NO_ERROR;
160
161   default:
162      ; /* fall-through */
163   }
164
165   /* now, for each format, check the type for compatibility */
166   switch (format) {
167      case GL_COLOR_INDEX:
168      case GL_STENCIL_INDEX:
169         switch (type) {
170            case GL_BITMAP:
171            case GL_BYTE:
172            case GL_UNSIGNED_BYTE:
173            case GL_SHORT:
174            case GL_UNSIGNED_SHORT:
175            case GL_INT:
176            case GL_UNSIGNED_INT:
177            case GL_FLOAT:
178               return GL_NO_ERROR;
179            case GL_HALF_FLOAT:
180               return ctx->Extensions.ARB_half_float_pixel
181                  ? GL_NO_ERROR : GL_INVALID_ENUM;
182            default:
183               return GL_INVALID_ENUM;
184         }
185
186      case GL_RED:
187      case GL_GREEN:
188      case GL_BLUE:
189      case GL_ALPHA:
190#if 0 /* not legal!  see table 3.6 of the 1.5 spec */
191      case GL_INTENSITY:
192#endif
193      case GL_LUMINANCE:
194      case GL_LUMINANCE_ALPHA:
195      case GL_DEPTH_COMPONENT:
196         switch (type) {
197            case GL_BYTE:
198            case GL_UNSIGNED_BYTE:
199            case GL_SHORT:
200            case GL_UNSIGNED_SHORT:
201            case GL_INT:
202            case GL_UNSIGNED_INT:
203            case GL_FLOAT:
204               return GL_NO_ERROR;
205            case GL_HALF_FLOAT:
206               return ctx->Extensions.ARB_half_float_pixel
207                  ? GL_NO_ERROR : GL_INVALID_ENUM;
208            default:
209               return GL_INVALID_ENUM;
210         }
211
212      case GL_RG:
213	 if (!ctx->Extensions.ARB_texture_rg)
214	    return GL_INVALID_ENUM;
215         switch (type) {
216            case GL_BYTE:
217            case GL_UNSIGNED_BYTE:
218            case GL_SHORT:
219            case GL_UNSIGNED_SHORT:
220            case GL_INT:
221            case GL_UNSIGNED_INT:
222            case GL_FLOAT:
223               return GL_NO_ERROR;
224            case GL_HALF_FLOAT:
225               return ctx->Extensions.ARB_half_float_pixel
226                  ? GL_NO_ERROR : GL_INVALID_ENUM;
227            default:
228               return GL_INVALID_ENUM;
229         }
230
231      case GL_RGB:
232         switch (type) {
233            case GL_BYTE:
234            case GL_UNSIGNED_BYTE:
235            case GL_SHORT:
236            case GL_UNSIGNED_SHORT:
237            case GL_INT:
238            case GL_UNSIGNED_INT:
239            case GL_FLOAT:
240            case GL_UNSIGNED_BYTE_3_3_2:
241            case GL_UNSIGNED_BYTE_2_3_3_REV:
242            case GL_UNSIGNED_SHORT_5_6_5:
243            case GL_UNSIGNED_SHORT_5_6_5_REV:
244               return GL_NO_ERROR;
245            case GL_HALF_FLOAT:
246               return ctx->Extensions.ARB_half_float_pixel
247                  ? GL_NO_ERROR : GL_INVALID_ENUM;
248            case GL_UNSIGNED_INT_5_9_9_9_REV:
249               return ctx->Extensions.EXT_texture_shared_exponent
250                  ? GL_NO_ERROR : GL_INVALID_ENUM;
251            case GL_UNSIGNED_INT_10F_11F_11F_REV:
252               return ctx->Extensions.EXT_packed_float
253                  ? GL_NO_ERROR : GL_INVALID_ENUM;
254            default:
255               return GL_INVALID_ENUM;
256         }
257
258      case GL_BGR:
259         switch (type) {
260            /* NOTE: no packed types are supported with BGR.  That's
261             * intentional, according to the GL spec.
262             */
263            case GL_BYTE:
264            case GL_UNSIGNED_BYTE:
265            case GL_SHORT:
266            case GL_UNSIGNED_SHORT:
267            case GL_INT:
268            case GL_UNSIGNED_INT:
269            case GL_FLOAT:
270               return GL_NO_ERROR;
271            case GL_HALF_FLOAT:
272               return ctx->Extensions.ARB_half_float_pixel
273                  ? GL_NO_ERROR : GL_INVALID_ENUM;
274            default:
275               return GL_INVALID_ENUM;
276         }
277
278      case GL_RGBA:
279      case GL_BGRA:
280      case GL_ABGR_EXT:
281         switch (type) {
282            case GL_BYTE:
283            case GL_UNSIGNED_BYTE:
284            case GL_SHORT:
285            case GL_UNSIGNED_SHORT:
286            case GL_INT:
287            case GL_UNSIGNED_INT:
288            case GL_FLOAT:
289            case GL_UNSIGNED_SHORT_4_4_4_4:
290            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
291            case GL_UNSIGNED_SHORT_5_5_5_1:
292            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
293            case GL_UNSIGNED_INT_8_8_8_8:
294            case GL_UNSIGNED_INT_8_8_8_8_REV:
295            case GL_UNSIGNED_INT_10_10_10_2:
296            case GL_UNSIGNED_INT_2_10_10_10_REV:
297               return GL_NO_ERROR;
298            case GL_HALF_FLOAT:
299               return ctx->Extensions.ARB_half_float_pixel
300                  ? GL_NO_ERROR : GL_INVALID_ENUM;
301            default:
302               return GL_INVALID_ENUM;
303         }
304
305      case GL_YCBCR_MESA:
306         if (!ctx->Extensions.MESA_ycbcr_texture)
307            return GL_INVALID_ENUM;
308         if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
309             type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
310            return GL_NO_ERROR;
311         else
312            return GL_INVALID_OPERATION;
313
314      case GL_DEPTH_STENCIL_EXT:
315         if (ctx->Extensions.EXT_packed_depth_stencil &&
316             type == GL_UNSIGNED_INT_24_8)
317            return GL_NO_ERROR;
318         else if (ctx->Extensions.ARB_depth_buffer_float &&
319             type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
320            return GL_NO_ERROR;
321         else
322            return GL_INVALID_ENUM;
323
324      case GL_DUDV_ATI:
325      case GL_DU8DV8_ATI:
326         if (!ctx->Extensions.ATI_envmap_bumpmap)
327            return GL_INVALID_ENUM;
328         switch (type) {
329            case GL_BYTE:
330            case GL_UNSIGNED_BYTE:
331            case GL_SHORT:
332            case GL_UNSIGNED_SHORT:
333            case GL_INT:
334            case GL_UNSIGNED_INT:
335            case GL_FLOAT:
336               return GL_NO_ERROR;
337            default:
338               return GL_INVALID_ENUM;
339         }
340
341      /* integer-valued formats */
342      case GL_RED_INTEGER_EXT:
343      case GL_GREEN_INTEGER_EXT:
344      case GL_BLUE_INTEGER_EXT:
345      case GL_ALPHA_INTEGER_EXT:
346      case GL_RG_INTEGER:
347         switch (type) {
348            case GL_BYTE:
349            case GL_UNSIGNED_BYTE:
350            case GL_SHORT:
351            case GL_UNSIGNED_SHORT:
352            case GL_INT:
353            case GL_UNSIGNED_INT:
354               return (ctx->VersionMajor >= 3 ||
355                       ctx->Extensions.EXT_texture_integer)
356                  ? GL_NO_ERROR : GL_INVALID_ENUM;
357            default:
358               return GL_INVALID_ENUM;
359         }
360
361      case GL_RGB_INTEGER_EXT:
362         switch (type) {
363            case GL_BYTE:
364            case GL_UNSIGNED_BYTE:
365            case GL_SHORT:
366            case GL_UNSIGNED_SHORT:
367            case GL_INT:
368            case GL_UNSIGNED_INT:
369               return (ctx->VersionMajor >= 3 ||
370                       ctx->Extensions.EXT_texture_integer)
371                  ? GL_NO_ERROR : GL_INVALID_ENUM;
372            case GL_UNSIGNED_BYTE_3_3_2:
373            case GL_UNSIGNED_BYTE_2_3_3_REV:
374            case GL_UNSIGNED_SHORT_5_6_5:
375            case GL_UNSIGNED_SHORT_5_6_5_REV:
376               return ctx->Extensions.ARB_texture_rgb10_a2ui
377                  ? GL_NO_ERROR : GL_INVALID_ENUM;
378            default:
379               return GL_INVALID_ENUM;
380         }
381
382      case GL_BGR_INTEGER_EXT:
383         switch (type) {
384            case GL_BYTE:
385            case GL_UNSIGNED_BYTE:
386            case GL_SHORT:
387            case GL_UNSIGNED_SHORT:
388            case GL_INT:
389            case GL_UNSIGNED_INT:
390            /* NOTE: no packed formats w/ BGR format */
391               return (ctx->VersionMajor >= 3 ||
392                       ctx->Extensions.EXT_texture_integer)
393                  ? GL_NO_ERROR : GL_INVALID_ENUM;
394            default:
395               return GL_INVALID_ENUM;
396         }
397
398      case GL_RGBA_INTEGER_EXT:
399      case GL_BGRA_INTEGER_EXT:
400         switch (type) {
401            case GL_BYTE:
402            case GL_UNSIGNED_BYTE:
403            case GL_SHORT:
404            case GL_UNSIGNED_SHORT:
405            case GL_INT:
406            case GL_UNSIGNED_INT:
407               return (ctx->VersionMajor >= 3 ||
408                       ctx->Extensions.EXT_texture_integer)
409                  ? GL_NO_ERROR : GL_INVALID_ENUM;
410            case GL_UNSIGNED_SHORT_4_4_4_4:
411            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
412            case GL_UNSIGNED_SHORT_5_5_5_1:
413            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
414            case GL_UNSIGNED_INT_8_8_8_8:
415            case GL_UNSIGNED_INT_8_8_8_8_REV:
416            case GL_UNSIGNED_INT_10_10_10_2:
417            case GL_UNSIGNED_INT_2_10_10_10_REV:
418               return ctx->Extensions.ARB_texture_rgb10_a2ui
419                  ? GL_NO_ERROR : GL_INVALID_ENUM;
420            default:
421               return GL_INVALID_ENUM;
422         }
423
424      case GL_LUMINANCE_INTEGER_EXT:
425      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
426         switch (type) {
427            case GL_BYTE:
428            case GL_UNSIGNED_BYTE:
429            case GL_SHORT:
430            case GL_UNSIGNED_SHORT:
431            case GL_INT:
432            case GL_UNSIGNED_INT:
433               return ctx->Extensions.EXT_texture_integer
434                  ? GL_NO_ERROR : GL_INVALID_ENUM;
435            default:
436               return GL_INVALID_ENUM;
437         }
438
439      default:
440         return GL_INVALID_ENUM;
441   }
442   return GL_NO_ERROR;
443}
444
445
446/**
447 * Return the byte offset of a specific pixel in an image (1D, 2D or 3D).
448 *
449 * Pixel unpacking/packing parameters are observed according to \p packing.
450 *
451 * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
452 * \param packing  the pixelstore attributes
453 * \param width  the image width
454 * \param height  the image height
455 * \param format  the pixel format (must be validated beforehand)
456 * \param type  the pixel data type (must be validated beforehand)
457 * \param img  which image in the volume (0 for 1D or 2D images)
458 * \param row  row of pixel in the image (0 for 1D images)
459 * \param column column of pixel in the image
460 *
461 * \return offset of pixel.
462 *
463 * \sa gl_pixelstore_attrib.
464 */
465GLintptr
466_mesa_image_offset( GLuint dimensions,
467                    const struct gl_pixelstore_attrib *packing,
468                    GLsizei width, GLsizei height,
469                    GLenum format, GLenum type,
470                    GLint img, GLint row, GLint column )
471{
472   GLint alignment;        /* 1, 2 or 4 */
473   GLint pixels_per_row;
474   GLint rows_per_image;
475   GLint skiprows;
476   GLint skippixels;
477   GLint skipimages;       /* for 3-D volume images */
478   GLintptr offset;
479
480   ASSERT(dimensions >= 1 && dimensions <= 3);
481
482   alignment = packing->Alignment;
483   if (packing->RowLength > 0) {
484      pixels_per_row = packing->RowLength;
485   }
486   else {
487      pixels_per_row = width;
488   }
489   if (packing->ImageHeight > 0) {
490      rows_per_image = packing->ImageHeight;
491   }
492   else {
493      rows_per_image = height;
494   }
495
496   skippixels = packing->SkipPixels;
497   /* Note: SKIP_ROWS _is_ used for 1D images */
498   skiprows = packing->SkipRows;
499   /* Note: SKIP_IMAGES is only used for 3D images */
500   skipimages = (dimensions == 3) ? packing->SkipImages : 0;
501
502   if (type == GL_BITMAP) {
503      /* BITMAP data */
504      GLint bytes_per_row;
505      GLint bytes_per_image;
506      /* components per pixel for color or stencil index: */
507      const GLint comp_per_pixel = 1;
508
509      /* The pixel type and format should have been error checked earlier */
510      assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX);
511
512      bytes_per_row = alignment
513                    * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
514
515      bytes_per_image = bytes_per_row * rows_per_image;
516
517      offset = (skipimages + img) * bytes_per_image
518                 + (skiprows + row) * bytes_per_row
519                 + (skippixels + column) / 8;
520   }
521   else {
522      /* Non-BITMAP data */
523      GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
524      GLint topOfImage;
525
526      bytes_per_pixel = _mesa_bytes_per_pixel( format, type );
527
528      /* The pixel type and format should have been error checked earlier */
529      assert(bytes_per_pixel > 0);
530
531      bytes_per_row = pixels_per_row * bytes_per_pixel;
532      remainder = bytes_per_row % alignment;
533      if (remainder > 0)
534         bytes_per_row += (alignment - remainder);
535
536      ASSERT(bytes_per_row % alignment == 0);
537
538      bytes_per_image = bytes_per_row * rows_per_image;
539
540      if (packing->Invert) {
541         /* set pixel_addr to the last row */
542         topOfImage = bytes_per_row * (height - 1);
543         bytes_per_row = -bytes_per_row;
544      }
545      else {
546         topOfImage = 0;
547      }
548
549      /* compute final pixel address */
550      offset = (skipimages + img) * bytes_per_image
551                 + topOfImage
552                 + (skiprows + row) * bytes_per_row
553                 + (skippixels + column) * bytes_per_pixel;
554   }
555
556   return offset;
557}
558
559
560/**
561 * Return the address of a specific pixel in an image (1D, 2D or 3D).
562 *
563 * Pixel unpacking/packing parameters are observed according to \p packing.
564 *
565 * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
566 * \param packing  the pixelstore attributes
567 * \param image  starting address of image data
568 * \param width  the image width
569 * \param height  the image height
570 * \param format  the pixel format (must be validated beforehand)
571 * \param type  the pixel data type (must be validated beforehand)
572 * \param img  which image in the volume (0 for 1D or 2D images)
573 * \param row  row of pixel in the image (0 for 1D images)
574 * \param column column of pixel in the image
575 *
576 * \return address of pixel.
577 *
578 * \sa gl_pixelstore_attrib.
579 */
580GLvoid *
581_mesa_image_address( GLuint dimensions,
582                     const struct gl_pixelstore_attrib *packing,
583                     const GLvoid *image,
584                     GLsizei width, GLsizei height,
585                     GLenum format, GLenum type,
586                     GLint img, GLint row, GLint column )
587{
588   const GLubyte *addr = (const GLubyte *) image;
589
590   addr += _mesa_image_offset(dimensions, packing, width, height,
591                              format, type, img, row, column);
592
593   return (GLvoid *) addr;
594}
595
596
597GLvoid *
598_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
599                       const GLvoid *image,
600                       GLsizei width,
601                       GLenum format, GLenum type,
602                       GLint column )
603{
604   return _mesa_image_address(1, packing, image, width, 1,
605                              format, type, 0, 0, column);
606}
607
608
609GLvoid *
610_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
611                       const GLvoid *image,
612                       GLsizei width, GLsizei height,
613                       GLenum format, GLenum type,
614                       GLint row, GLint column )
615{
616   return _mesa_image_address(2, packing, image, width, height,
617                              format, type, 0, row, column);
618}
619
620
621GLvoid *
622_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
623                       const GLvoid *image,
624                       GLsizei width, GLsizei height,
625                       GLenum format, GLenum type,
626                       GLint img, GLint row, GLint column )
627{
628   return _mesa_image_address(3, packing, image, width, height,
629                              format, type, img, row, column);
630}
631
632
633
634/**
635 * Compute the stride (in bytes) between image rows.
636 *
637 * \param packing the pixelstore attributes
638 * \param width image width.
639 * \param format pixel format.
640 * \param type pixel data type.
641 *
642 * \return the stride in bytes for the given parameters, or -1 if error
643 */
644GLint
645_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
646                        GLint width, GLenum format, GLenum type )
647{
648   GLint bytesPerRow, remainder;
649
650   ASSERT(packing);
651
652   if (type == GL_BITMAP) {
653      if (packing->RowLength == 0) {
654         bytesPerRow = (width + 7) / 8;
655      }
656      else {
657         bytesPerRow = (packing->RowLength + 7) / 8;
658      }
659   }
660   else {
661      /* Non-BITMAP data */
662      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
663      if (bytesPerPixel <= 0)
664         return -1;  /* error */
665      if (packing->RowLength == 0) {
666         bytesPerRow = bytesPerPixel * width;
667      }
668      else {
669         bytesPerRow = bytesPerPixel * packing->RowLength;
670      }
671   }
672
673   remainder = bytesPerRow % packing->Alignment;
674   if (remainder > 0) {
675      bytesPerRow += (packing->Alignment - remainder);
676   }
677
678   if (packing->Invert) {
679      /* negate the bytes per row (negative row stride) */
680      bytesPerRow = -bytesPerRow;
681   }
682
683   return bytesPerRow;
684}
685
686
687/*
688 * Compute the stride between images in a 3D texture (in bytes) for the given
689 * pixel packing parameters and image width, format and type.
690 */
691GLint
692_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
693                          GLint width, GLint height,
694                          GLenum format, GLenum type )
695{
696   GLint bytesPerRow, bytesPerImage, remainder;
697
698   ASSERT(packing);
699
700   if (type == GL_BITMAP) {
701      if (packing->RowLength == 0) {
702         bytesPerRow = (width + 7) / 8;
703      }
704      else {
705         bytesPerRow = (packing->RowLength + 7) / 8;
706      }
707   }
708   else {
709      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
710
711      if (bytesPerPixel <= 0)
712         return -1;  /* error */
713      if (packing->RowLength == 0) {
714         bytesPerRow = bytesPerPixel * width;
715      }
716      else {
717         bytesPerRow = bytesPerPixel * packing->RowLength;
718      }
719   }
720
721   remainder = bytesPerRow % packing->Alignment;
722   if (remainder > 0)
723      bytesPerRow += (packing->Alignment - remainder);
724
725   if (packing->ImageHeight == 0)
726      bytesPerImage = bytesPerRow * height;
727   else
728      bytesPerImage = bytesPerRow * packing->ImageHeight;
729
730   return bytesPerImage;
731}
732
733
734
735/**
736 * "Expand" a bitmap from 1-bit per pixel to 8-bits per pixel.
737 * This is typically used to convert a bitmap into a GLubyte/pixel texture.
738 * "On" bits will set texels to \p onValue.
739 * "Off" bits will not modify texels.
740 * \param width  src bitmap width in pixels
741 * \param height  src bitmap height in pixels
742 * \param unpack  bitmap unpacking state
743 * \param bitmap  the src bitmap data
744 * \param destBuffer  start of dest buffer
745 * \param destStride  row stride in dest buffer
746 * \param onValue  if bit is 1, set destBuffer pixel to this value
747 */
748void
749_mesa_expand_bitmap(GLsizei width, GLsizei height,
750                    const struct gl_pixelstore_attrib *unpack,
751                    const GLubyte *bitmap,
752                    GLubyte *destBuffer, GLint destStride,
753                    GLubyte onValue)
754{
755   const GLubyte *srcRow = (const GLubyte *)
756      _mesa_image_address2d(unpack, bitmap, width, height,
757                            GL_COLOR_INDEX, GL_BITMAP, 0, 0);
758   const GLint srcStride = _mesa_image_row_stride(unpack, width,
759                                                  GL_COLOR_INDEX, GL_BITMAP);
760   GLint row, col;
761
762#define SET_PIXEL(COL, ROW) \
763   destBuffer[(ROW) * destStride + (COL)] = onValue;
764
765   for (row = 0; row < height; row++) {
766      const GLubyte *src = srcRow;
767
768      if (unpack->LsbFirst) {
769         /* Lsb first */
770         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
771         for (col = 0; col < width; col++) {
772
773            if (*src & mask) {
774               SET_PIXEL(col, row);
775            }
776
777            if (mask == 128U) {
778               src++;
779               mask = 1U;
780            }
781            else {
782               mask = mask << 1;
783            }
784         }
785
786         /* get ready for next row */
787         if (mask != 1)
788            src++;
789      }
790      else {
791         /* Msb first */
792         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
793         for (col = 0; col < width; col++) {
794
795            if (*src & mask) {
796               SET_PIXEL(col, row);
797            }
798
799            if (mask == 1U) {
800               src++;
801               mask = 128U;
802            }
803            else {
804               mask = mask >> 1;
805            }
806         }
807
808         /* get ready for next row */
809         if (mask != 128)
810            src++;
811      }
812
813      srcRow += srcStride;
814   } /* row */
815
816#undef SET_PIXEL
817}
818
819
820
821
822/**
823 * Convert an array of RGBA colors from one datatype to another.
824 * NOTE: src may equal dst.  In that case, we use a temporary buffer.
825 */
826void
827_mesa_convert_colors(GLenum srcType, const GLvoid *src,
828                     GLenum dstType, GLvoid *dst,
829                     GLuint count, const GLubyte mask[])
830{
831   GLuint *tempBuffer;
832   const GLboolean useTemp = (src == dst);
833
834   tempBuffer = malloc(count * MAX_PIXEL_BYTES);
835   if (!tempBuffer)
836      return;
837
838   ASSERT(srcType != dstType);
839
840   switch (srcType) {
841   case GL_UNSIGNED_BYTE:
842      if (dstType == GL_UNSIGNED_SHORT) {
843         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
844         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
845         GLuint i;
846         for (i = 0; i < count; i++) {
847            if (!mask || mask[i]) {
848               dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]);
849               dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]);
850               dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]);
851               dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]);
852            }
853         }
854         if (useTemp)
855            memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
856      }
857      else {
858         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
859         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
860         GLuint i;
861         ASSERT(dstType == GL_FLOAT);
862         for (i = 0; i < count; i++) {
863            if (!mask || mask[i]) {
864               dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]);
865               dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]);
866               dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]);
867               dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]);
868            }
869         }
870         if (useTemp)
871            memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
872      }
873      break;
874   case GL_UNSIGNED_SHORT:
875      if (dstType == GL_UNSIGNED_BYTE) {
876         const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
877         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);
878         GLuint i;
879         for (i = 0; i < count; i++) {
880            if (!mask || mask[i]) {
881               dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]);
882               dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]);
883               dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]);
884               dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]);
885            }
886         }
887         if (useTemp)
888            memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
889      }
890      else {
891         const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
892         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
893         GLuint i;
894         ASSERT(dstType == GL_FLOAT);
895         for (i = 0; i < count; i++) {
896            if (!mask || mask[i]) {
897               dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]);
898               dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]);
899               dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]);
900               dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]);
901            }
902         }
903         if (useTemp)
904            memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
905      }
906      break;
907   case GL_FLOAT:
908      if (dstType == GL_UNSIGNED_BYTE) {
909         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
910         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);
911         GLuint i;
912         for (i = 0; i < count; i++) {
913            if (!mask || mask[i])
914               _mesa_unclamped_float_rgba_to_ubyte(dst1[i], src4[i]);
915         }
916         if (useTemp)
917            memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
918      }
919      else {
920         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
921         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
922         GLuint i;
923         ASSERT(dstType == GL_UNSIGNED_SHORT);
924         for (i = 0; i < count; i++) {
925            if (!mask || mask[i]) {
926               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]);
927               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]);
928               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]);
929               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]);
930            }
931         }
932         if (useTemp)
933            memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
934      }
935      break;
936   default:
937      _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors");
938   }
939
940   free(tempBuffer);
941}
942
943
944
945
946/**
947 * Perform basic clipping for glDrawPixels.  The image's position and size
948 * and the unpack SkipPixels and SkipRows are adjusted so that the image
949 * region is entirely within the window and scissor bounds.
950 * NOTE: this will only work when glPixelZoom is (1, 1) or (1, -1).
951 * If Pixel.ZoomY is -1, *destY will be changed to be the first row which
952 * we'll actually write.  Beforehand, *destY-1 is the first drawing row.
953 *
954 * \return  GL_TRUE if image is ready for drawing or
955 *          GL_FALSE if image was completely clipped away (draw nothing)
956 */
957GLboolean
958_mesa_clip_drawpixels(const struct gl_context *ctx,
959                      GLint *destX, GLint *destY,
960                      GLsizei *width, GLsizei *height,
961                      struct gl_pixelstore_attrib *unpack)
962{
963   const struct gl_framebuffer *buffer = ctx->DrawBuffer;
964
965   if (unpack->RowLength == 0) {
966      unpack->RowLength = *width;
967   }
968
969   ASSERT(ctx->Pixel.ZoomX == 1.0F);
970   ASSERT(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F);
971
972   /* left clipping */
973   if (*destX < buffer->_Xmin) {
974      unpack->SkipPixels += (buffer->_Xmin - *destX);
975      *width -= (buffer->_Xmin - *destX);
976      *destX = buffer->_Xmin;
977   }
978   /* right clipping */
979   if (*destX + *width > buffer->_Xmax)
980      *width -= (*destX + *width - buffer->_Xmax);
981
982   if (*width <= 0)
983      return GL_FALSE;
984
985   if (ctx->Pixel.ZoomY == 1.0F) {
986      /* bottom clipping */
987      if (*destY < buffer->_Ymin) {
988         unpack->SkipRows += (buffer->_Ymin - *destY);
989         *height -= (buffer->_Ymin - *destY);
990         *destY = buffer->_Ymin;
991      }
992      /* top clipping */
993      if (*destY + *height > buffer->_Ymax)
994         *height -= (*destY + *height - buffer->_Ymax);
995   }
996   else { /* upside down */
997      /* top clipping */
998      if (*destY > buffer->_Ymax) {
999         unpack->SkipRows += (*destY - buffer->_Ymax);
1000         *height -= (*destY - buffer->_Ymax);
1001         *destY = buffer->_Ymax;
1002      }
1003      /* bottom clipping */
1004      if (*destY - *height < buffer->_Ymin)
1005         *height -= (buffer->_Ymin - (*destY - *height));
1006      /* adjust destY so it's the first row to write to */
1007      (*destY)--;
1008   }
1009
1010   if (*height <= 0)
1011      return GL_FALSE;
1012
1013   return GL_TRUE;
1014}
1015
1016
1017/**
1018 * Perform clipping for glReadPixels.  The image's window position
1019 * and size, and the pack skipPixels, skipRows and rowLength are adjusted
1020 * so that the image region is entirely within the window bounds.
1021 * Note: this is different from _mesa_clip_drawpixels() in that the
1022 * scissor box is ignored, and we use the bounds of the current readbuffer
1023 * surface.
1024 *
1025 * \return  GL_TRUE if region to read is in bounds
1026 *          GL_FALSE if region is completely out of bounds (nothing to read)
1027 */
1028GLboolean
1029_mesa_clip_readpixels(const struct gl_context *ctx,
1030                      GLint *srcX, GLint *srcY,
1031                      GLsizei *width, GLsizei *height,
1032                      struct gl_pixelstore_attrib *pack)
1033{
1034   const struct gl_framebuffer *buffer = ctx->ReadBuffer;
1035
1036   if (pack->RowLength == 0) {
1037      pack->RowLength = *width;
1038   }
1039
1040   /* left clipping */
1041   if (*srcX < 0) {
1042      pack->SkipPixels += (0 - *srcX);
1043      *width -= (0 - *srcX);
1044      *srcX = 0;
1045   }
1046   /* right clipping */
1047   if (*srcX + *width > (GLsizei) buffer->Width)
1048      *width -= (*srcX + *width - buffer->Width);
1049
1050   if (*width <= 0)
1051      return GL_FALSE;
1052
1053   /* bottom clipping */
1054   if (*srcY < 0) {
1055      pack->SkipRows += (0 - *srcY);
1056      *height -= (0 - *srcY);
1057      *srcY = 0;
1058   }
1059   /* top clipping */
1060   if (*srcY + *height > (GLsizei) buffer->Height)
1061      *height -= (*srcY + *height - buffer->Height);
1062
1063   if (*height <= 0)
1064      return GL_FALSE;
1065
1066   return GL_TRUE;
1067}
1068
1069
1070/**
1071 * Do clipping for a glCopyTexSubImage call.
1072 * The framebuffer source region might extend outside the framebuffer
1073 * bounds.  Clip the source region against the framebuffer bounds and
1074 * adjust the texture/dest position and size accordingly.
1075 *
1076 * \return GL_FALSE if region is totally clipped, GL_TRUE otherwise.
1077 */
1078GLboolean
1079_mesa_clip_copytexsubimage(const struct gl_context *ctx,
1080                           GLint *destX, GLint *destY,
1081                           GLint *srcX, GLint *srcY,
1082                           GLsizei *width, GLsizei *height)
1083{
1084   const struct gl_framebuffer *fb = ctx->ReadBuffer;
1085   const GLint srcX0 = *srcX, srcY0 = *srcY;
1086
1087   if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height,
1088                            srcX, srcY, width, height)) {
1089      *destX = *destX + *srcX - srcX0;
1090      *destY = *destY + *srcY - srcY0;
1091
1092      return GL_TRUE;
1093   }
1094   else {
1095      return GL_FALSE;
1096   }
1097}
1098
1099
1100
1101/**
1102 * Clip the rectangle defined by (x, y, width, height) against the bounds
1103 * specified by [xmin, xmax) and [ymin, ymax).
1104 * \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise.
1105 */
1106GLboolean
1107_mesa_clip_to_region(GLint xmin, GLint ymin,
1108                     GLint xmax, GLint ymax,
1109                     GLint *x, GLint *y,
1110                     GLsizei *width, GLsizei *height )
1111{
1112   /* left clipping */
1113   if (*x < xmin) {
1114      *width -= (xmin - *x);
1115      *x = xmin;
1116   }
1117
1118   /* right clipping */
1119   if (*x + *width > xmax)
1120      *width -= (*x + *width - xmax);
1121
1122   if (*width <= 0)
1123      return GL_FALSE;
1124
1125   /* bottom (or top) clipping */
1126   if (*y < ymin) {
1127      *height -= (ymin - *y);
1128      *y = ymin;
1129   }
1130
1131   /* top (or bottom) clipping */
1132   if (*y + *height > ymax)
1133      *height -= (*y + *height - ymax);
1134
1135   if (*height <= 0)
1136      return GL_FALSE;
1137
1138   return GL_TRUE;
1139}
1140
1141
1142/**
1143 * Clip dst coords against Xmax (or Ymax).
1144 */
1145static inline void
1146clip_right_or_top(GLint *srcX0, GLint *srcX1,
1147                  GLint *dstX0, GLint *dstX1,
1148                  GLint maxValue)
1149{
1150   GLfloat t, bias;
1151
1152   if (*dstX1 > maxValue) {
1153      /* X1 outside right edge */
1154      ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
1155      t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
1156      /* chop off [t, 1] part */
1157      ASSERT(t >= 0.0 && t <= 1.0);
1158      *dstX1 = maxValue;
1159      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
1160      *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
1161   }
1162   else if (*dstX0 > maxValue) {
1163      /* X0 outside right edge */
1164      ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
1165      t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
1166      /* chop off [t, 1] part */
1167      ASSERT(t >= 0.0 && t <= 1.0);
1168      *dstX0 = maxValue;
1169      bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F;
1170      *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
1171   }
1172}
1173
1174
1175/**
1176 * Clip dst coords against Xmin (or Ymin).
1177 */
1178static inline void
1179clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
1180                    GLint *dstX0, GLint *dstX1,
1181                    GLint minValue)
1182{
1183   GLfloat t, bias;
1184
1185   if (*dstX0 < minValue) {
1186      /* X0 outside left edge */
1187      ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
1188      t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
1189      /* chop off [0, t] part */
1190      ASSERT(t >= 0.0 && t <= 1.0);
1191      *dstX0 = minValue;
1192      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; /* flipped??? */
1193      *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
1194   }
1195   else if (*dstX1 < minValue) {
1196      /* X1 outside left edge */
1197      ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
1198      t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
1199      /* chop off [0, t] part */
1200      ASSERT(t >= 0.0 && t <= 1.0);
1201      *dstX1 = minValue;
1202      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
1203      *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
1204   }
1205}
1206
1207
1208/**
1209 * Do clipping of blit src/dest rectangles.
1210 * The dest rect is clipped against both the buffer bounds and scissor bounds.
1211 * The src rect is just clipped against the buffer bounds.
1212 *
1213 * When either the src or dest rect is clipped, the other is also clipped
1214 * proportionately!
1215 *
1216 * Note that X0 need not be less than X1 (same for Y) for either the source
1217 * and dest rects.  That makes the clipping a little trickier.
1218 *
1219 * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
1220 */
1221GLboolean
1222_mesa_clip_blit(struct gl_context *ctx,
1223                GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
1224                GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
1225{
1226   const GLint srcXmin = 0;
1227   const GLint srcXmax = ctx->ReadBuffer->Width;
1228   const GLint srcYmin = 0;
1229   const GLint srcYmax = ctx->ReadBuffer->Height;
1230
1231   /* these include scissor bounds */
1232   const GLint dstXmin = ctx->DrawBuffer->_Xmin;
1233   const GLint dstXmax = ctx->DrawBuffer->_Xmax;
1234   const GLint dstYmin = ctx->DrawBuffer->_Ymin;
1235   const GLint dstYmax = ctx->DrawBuffer->_Ymax;
1236
1237   /*
1238   printf("PreClipX:  src: %d .. %d  dst: %d .. %d\n",
1239          *srcX0, *srcX1, *dstX0, *dstX1);
1240   printf("PreClipY:  src: %d .. %d  dst: %d .. %d\n",
1241          *srcY0, *srcY1, *dstY0, *dstY1);
1242   */
1243
1244   /* trivial rejection tests */
1245   if (*dstX0 == *dstX1)
1246      return GL_FALSE; /* no width */
1247   if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
1248      return GL_FALSE; /* totally out (left) of bounds */
1249   if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
1250      return GL_FALSE; /* totally out (right) of bounds */
1251
1252   if (*dstY0 == *dstY1)
1253      return GL_FALSE;
1254   if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
1255      return GL_FALSE;
1256   if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
1257      return GL_FALSE;
1258
1259   if (*srcX0 == *srcX1)
1260      return GL_FALSE;
1261   if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
1262      return GL_FALSE;
1263   if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
1264      return GL_FALSE;
1265
1266   if (*srcY0 == *srcY1)
1267      return GL_FALSE;
1268   if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
1269      return GL_FALSE;
1270   if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
1271      return GL_FALSE;
1272
1273   /*
1274    * dest clip
1275    */
1276   clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
1277   clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
1278   clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
1279   clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
1280
1281   /*
1282    * src clip (just swap src/dst values from above)
1283    */
1284   clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
1285   clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
1286   clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
1287   clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
1288
1289   /*
1290   printf("PostClipX: src: %d .. %d  dst: %d .. %d\n",
1291          *srcX0, *srcX1, *dstX0, *dstX1);
1292   printf("PostClipY: src: %d .. %d  dst: %d .. %d\n",
1293          *srcY0, *srcY1, *dstY0, *dstY1);
1294   */
1295
1296   ASSERT(*dstX0 >= dstXmin);
1297   ASSERT(*dstX0 <= dstXmax);
1298   ASSERT(*dstX1 >= dstXmin);
1299   ASSERT(*dstX1 <= dstXmax);
1300
1301   ASSERT(*dstY0 >= dstYmin);
1302   ASSERT(*dstY0 <= dstYmax);
1303   ASSERT(*dstY1 >= dstYmin);
1304   ASSERT(*dstY1 <= dstYmax);
1305
1306   ASSERT(*srcX0 >= srcXmin);
1307   ASSERT(*srcX0 <= srcXmax);
1308   ASSERT(*srcX1 >= srcXmin);
1309   ASSERT(*srcX1 <= srcXmax);
1310
1311   ASSERT(*srcY0 >= srcYmin);
1312   ASSERT(*srcY0 <= srcYmax);
1313   ASSERT(*srcY1 >= srcYmin);
1314   ASSERT(*srcY1 <= srcYmax);
1315
1316   return GL_TRUE;
1317}
1318