1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach/* 2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * Mesa 3-D graphics library 35e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 418d2822905ac3187318bd662f80c2836bdfa7c1fBrian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5995456f9305593005f8466520314ee087f3d422aBrian Paul * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 65e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * Permission is hereby granted, free of charge, to any person obtaining a 8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * copy of this software and associated documentation files (the "Software"), 9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * to deal in the Software without restriction, including without limitation 10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * and/or sell copies of the Software, and to permit persons to whom the 12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * Software is furnished to do so, subject to the following conditions: 135e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * The above copyright notice and this permission notice shall be included 15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * in all copies or substantial portions of the Software. 165e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 203d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 213d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 223d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 233d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER DEALINGS IN THE SOFTWARE. 24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach */ 25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 27f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/** 28f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \file image.c 29f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Image handling. 30f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */ 31f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 32f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul 33fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul#include "glheader.h" 34c893a015d8a50a38cd3f727d99835e7e7e2ccea9Brian Paul#include "colormac.h" 35a1287f549a3e6527b8cf3bf5b5f563ba63c6f48cBrian Paul#include "glformats.h" 36afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach#include "image.h" 373c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h" 38afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach#include "macros.h" 390117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h" 40afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 41afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 4227558a160a9fe91745728d7626995cd88f8fe339Brian Paul 436dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** 44a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * Flip the order of the 2 bytes in each word in the given array (src) and 45a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * store the result in another array (dst). For in-place byte-swapping this 46a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * function can be called with the same array for src and dst. 476dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 48a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * \param dst the array where byte-swapped data will be stored. 49a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * \param src the array with the source data we want to byte-swap. 506dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of words. 51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach */ 520ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airliestatic void 530ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlieswap2_copy( GLushort *dst, GLushort *src, GLuint n ) 54afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach{ 55f0707c789a4c8f02b9b9f51012bd41691779e166Brian Paul GLuint i; 56f0707c789a4c8f02b9b9f51012bd41691779e166Brian Paul for (i = 0; i < n; i++) { 57a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga dst[i] = (src[i] >> 8) | ((src[i] << 8) & 0xff00); 58afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 59afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach} 60afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 610ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlievoid 620ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie_mesa_swap2(GLushort *p, GLuint n) 630ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie{ 640ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie swap2_copy(p, p, n); 650ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie} 66afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 67afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach/* 68a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * Flip the order of the 4 bytes in each word in the given array (src) and 69a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * store the result in another array (dst). For in-place byte-swapping this 70a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * function can be called with the same array for src and dst. 71a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * 72a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * \param dst the array where byte-swapped data will be stored. 73a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * \param src the array with the source data we want to byte-swap. 74a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga * \param n number of words. 75afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach */ 760ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airliestatic void 770ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlieswap4_copy( GLuint *dst, GLuint *src, GLuint n ) 78afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach{ 79f0707c789a4c8f02b9b9f51012bd41691779e166Brian Paul GLuint i, a, b; 80f0707c789a4c8f02b9b9f51012bd41691779e166Brian Paul for (i = 0; i < n; i++) { 81a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga b = src[i]; 82afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach a = (b >> 24) 83afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach | ((b >> 8) & 0xff00) 84afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach | ((b << 8) & 0xff0000) 85afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach | ((b << 24) & 0xff000000); 86a177b30f1f2a74c14a649e9990eaab8826523c69Iago Toral Quiroga dst[i] = a; 87afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 88afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach} 89afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 900ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlievoid 910ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie_mesa_swap4(GLuint *p, GLuint n) 920ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie{ 930ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie swap4_copy(p, p, n); 940ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie} 95afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 966dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** 974a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * Return the byte offset of a specific pixel in an image (1D, 2D or 3D). 986dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 996dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Pixel unpacking/packing parameters are observed according to \p packing. 1006dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 10160909388ab136d849d99eab49e782a53772a618fBrian Paul * \param dimensions either 1, 2 or 3 to indicate dimensionality of image 102f22421e9b9ae08512d02927c85e8a7c69867856fnobled * \param packing the pixelstore attributes 10360909388ab136d849d99eab49e782a53772a618fBrian Paul * \param width the image width 104f22421e9b9ae08512d02927c85e8a7c69867856fnobled * \param height the image height 105f22421e9b9ae08512d02927c85e8a7c69867856fnobled * \param format the pixel format (must be validated beforehand) 106f22421e9b9ae08512d02927c85e8a7c69867856fnobled * \param type the pixel data type (must be validated beforehand) 10760909388ab136d849d99eab49e782a53772a618fBrian Paul * \param img which image in the volume (0 for 1D or 2D images) 10860909388ab136d849d99eab49e782a53772a618fBrian Paul * \param row row of pixel in the image (0 for 1D images) 10960909388ab136d849d99eab49e782a53772a618fBrian Paul * \param column column of pixel in the image 1104a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * 1114a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \return offset of pixel. 1126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 1136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa gl_pixelstore_attrib. 114afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach */ 1154a2b9b53052a74e71aac59592e95e3910b5b7da5nobledGLintptr 1164a2b9b53052a74e71aac59592e95e3910b5b7da5nobled_mesa_image_offset( GLuint dimensions, 1174a2b9b53052a74e71aac59592e95e3910b5b7da5nobled const struct gl_pixelstore_attrib *packing, 1184a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLsizei width, GLsizei height, 1194a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLenum format, GLenum type, 1204a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLint img, GLint row, GLint column ) 121afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach{ 122afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach GLint alignment; /* 1, 2 or 4 */ 123afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach GLint pixels_per_row; 124afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach GLint rows_per_image; 125afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach GLint skiprows; 126afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach GLint skippixels; 127afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach GLint skipimages; /* for 3-D volume images */ 1284a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLintptr offset; 129afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 130bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(dimensions >= 1 && dimensions <= 3); 13160909388ab136d849d99eab49e782a53772a618fBrian Paul 132afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach alignment = packing->Alignment; 133afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach if (packing->RowLength > 0) { 134afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach pixels_per_row = packing->RowLength; 135afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach else { 137afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach pixels_per_row = width; 138afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 139afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach if (packing->ImageHeight > 0) { 140afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach rows_per_image = packing->ImageHeight; 141afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 142afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach else { 143afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach rows_per_image = height; 144afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 14560909388ab136d849d99eab49e782a53772a618fBrian Paul 146afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach skippixels = packing->SkipPixels; 14760909388ab136d849d99eab49e782a53772a618fBrian Paul /* Note: SKIP_ROWS _is_ used for 1D images */ 14860909388ab136d849d99eab49e782a53772a618fBrian Paul skiprows = packing->SkipRows; 14960909388ab136d849d99eab49e782a53772a618fBrian Paul /* Note: SKIP_IMAGES is only used for 3D images */ 15060909388ab136d849d99eab49e782a53772a618fBrian Paul skipimages = (dimensions == 3) ? packing->SkipImages : 0; 151afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 152450e917c9d71f696bca2ba11960a521e64385ec2Brian Paul if (type == GL_BITMAP) { 153afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach /* BITMAP data */ 1546510e0734563ff8d30e45b8781153367db15cc5bNicolai Hähnle GLintptr bytes_per_row; 1556510e0734563ff8d30e45b8781153367db15cc5bNicolai Hähnle GLintptr bytes_per_image; 156f22421e9b9ae08512d02927c85e8a7c69867856fnobled /* components per pixel for color or stencil index: */ 157f22421e9b9ae08512d02927c85e8a7c69867856fnobled const GLint comp_per_pixel = 1; 158afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 159f22421e9b9ae08512d02927c85e8a7c69867856fnobled /* The pixel type and format should have been error checked earlier */ 160f22421e9b9ae08512d02927c85e8a7c69867856fnobled assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX); 161afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 162afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach bytes_per_row = alignment 163818585b9f9ccd55b992e35f4d74120f0e879559fFrancisco Jerez * DIV_ROUND_UP( comp_per_pixel*pixels_per_row, 8*alignment ); 164afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 165afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach bytes_per_image = bytes_per_row * rows_per_image; 166afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 1674a2b9b53052a74e71aac59592e95e3910b5b7da5nobled offset = (skipimages + img) * bytes_per_image 168afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach + (skiprows + row) * bytes_per_row 169afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach + (skippixels + column) / 8; 170afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 171afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach else { 172afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach /* Non-BITMAP data */ 1736510e0734563ff8d30e45b8781153367db15cc5bNicolai Hähnle GLintptr bytes_per_pixel, bytes_per_row, remainder, bytes_per_image; 1746510e0734563ff8d30e45b8781153367db15cc5bNicolai Hähnle GLintptr topOfImage; 175afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 176b7d076fc96ac27117421653a043d00a95f789d24Brian Paul bytes_per_pixel = _mesa_bytes_per_pixel( format, type ); 177afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 178afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach /* The pixel type and format should have been error checked earlier */ 179afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach assert(bytes_per_pixel > 0); 180afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 181afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach bytes_per_row = pixels_per_row * bytes_per_pixel; 182afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach remainder = bytes_per_row % alignment; 183afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach if (remainder > 0) 184afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach bytes_per_row += (alignment - remainder); 185afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 186bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(bytes_per_row % alignment == 0); 187afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 188afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach bytes_per_image = bytes_per_row * rows_per_image; 189afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 190551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul if (packing->Invert) { 191551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul /* set pixel_addr to the last row */ 192551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul topOfImage = bytes_per_row * (height - 1); 193551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul bytes_per_row = -bytes_per_row; 194551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul } 195551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul else { 196551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul topOfImage = 0; 197551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul } 198551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul 199afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach /* compute final pixel address */ 2004a2b9b53052a74e71aac59592e95e3910b5b7da5nobled offset = (skipimages + img) * bytes_per_image 201551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul + topOfImage 202afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach + (skiprows + row) * bytes_per_row 203afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach + (skippixels + column) * bytes_per_pixel; 204afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 205afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 2064a2b9b53052a74e71aac59592e95e3910b5b7da5nobled return offset; 2074a2b9b53052a74e71aac59592e95e3910b5b7da5nobled} 2084a2b9b53052a74e71aac59592e95e3910b5b7da5nobled 2094a2b9b53052a74e71aac59592e95e3910b5b7da5nobled 2104a2b9b53052a74e71aac59592e95e3910b5b7da5nobled/** 2114a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * Return the address of a specific pixel in an image (1D, 2D or 3D). 2124a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * 2134a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * Pixel unpacking/packing parameters are observed according to \p packing. 2144a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * 2154a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param dimensions either 1, 2 or 3 to indicate dimensionality of image 2164a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param packing the pixelstore attributes 2174a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param image starting address of image data 2184a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param width the image width 2194a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param height the image height 2204a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param format the pixel format (must be validated beforehand) 2214a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param type the pixel data type (must be validated beforehand) 2224a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param img which image in the volume (0 for 1D or 2D images) 2234a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param row row of pixel in the image (0 for 1D images) 2244a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \param column column of pixel in the image 2254a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * 2264a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \return address of pixel. 2274a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * 2284a2b9b53052a74e71aac59592e95e3910b5b7da5nobled * \sa gl_pixelstore_attrib. 2294a2b9b53052a74e71aac59592e95e3910b5b7da5nobled */ 2304a2b9b53052a74e71aac59592e95e3910b5b7da5nobledGLvoid * 2314a2b9b53052a74e71aac59592e95e3910b5b7da5nobled_mesa_image_address( GLuint dimensions, 2324a2b9b53052a74e71aac59592e95e3910b5b7da5nobled const struct gl_pixelstore_attrib *packing, 2334a2b9b53052a74e71aac59592e95e3910b5b7da5nobled const GLvoid *image, 2344a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLsizei width, GLsizei height, 2354a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLenum format, GLenum type, 2364a2b9b53052a74e71aac59592e95e3910b5b7da5nobled GLint img, GLint row, GLint column ) 2374a2b9b53052a74e71aac59592e95e3910b5b7da5nobled{ 2384a2b9b53052a74e71aac59592e95e3910b5b7da5nobled const GLubyte *addr = (const GLubyte *) image; 2394a2b9b53052a74e71aac59592e95e3910b5b7da5nobled 2404a2b9b53052a74e71aac59592e95e3910b5b7da5nobled addr += _mesa_image_offset(dimensions, packing, width, height, 2414a2b9b53052a74e71aac59592e95e3910b5b7da5nobled format, type, img, row, column); 2424a2b9b53052a74e71aac59592e95e3910b5b7da5nobled 2434a2b9b53052a74e71aac59592e95e3910b5b7da5nobled return (GLvoid *) addr; 244afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach} 245afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 246afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 24760909388ab136d849d99eab49e782a53772a618fBrian PaulGLvoid * 24860909388ab136d849d99eab49e782a53772a618fBrian Paul_mesa_image_address1d( const struct gl_pixelstore_attrib *packing, 24960909388ab136d849d99eab49e782a53772a618fBrian Paul const GLvoid *image, 25060909388ab136d849d99eab49e782a53772a618fBrian Paul GLsizei width, 25160909388ab136d849d99eab49e782a53772a618fBrian Paul GLenum format, GLenum type, 25260909388ab136d849d99eab49e782a53772a618fBrian Paul GLint column ) 25360909388ab136d849d99eab49e782a53772a618fBrian Paul{ 25460909388ab136d849d99eab49e782a53772a618fBrian Paul return _mesa_image_address(1, packing, image, width, 1, 25560909388ab136d849d99eab49e782a53772a618fBrian Paul format, type, 0, 0, column); 25660909388ab136d849d99eab49e782a53772a618fBrian Paul} 25760909388ab136d849d99eab49e782a53772a618fBrian Paul 25860909388ab136d849d99eab49e782a53772a618fBrian Paul 25960909388ab136d849d99eab49e782a53772a618fBrian PaulGLvoid * 26060909388ab136d849d99eab49e782a53772a618fBrian Paul_mesa_image_address2d( const struct gl_pixelstore_attrib *packing, 26160909388ab136d849d99eab49e782a53772a618fBrian Paul const GLvoid *image, 26260909388ab136d849d99eab49e782a53772a618fBrian Paul GLsizei width, GLsizei height, 26360909388ab136d849d99eab49e782a53772a618fBrian Paul GLenum format, GLenum type, 26460909388ab136d849d99eab49e782a53772a618fBrian Paul GLint row, GLint column ) 26560909388ab136d849d99eab49e782a53772a618fBrian Paul{ 26660909388ab136d849d99eab49e782a53772a618fBrian Paul return _mesa_image_address(2, packing, image, width, height, 26760909388ab136d849d99eab49e782a53772a618fBrian Paul format, type, 0, row, column); 26860909388ab136d849d99eab49e782a53772a618fBrian Paul} 26960909388ab136d849d99eab49e782a53772a618fBrian Paul 27060909388ab136d849d99eab49e782a53772a618fBrian Paul 27160909388ab136d849d99eab49e782a53772a618fBrian PaulGLvoid * 27260909388ab136d849d99eab49e782a53772a618fBrian Paul_mesa_image_address3d( const struct gl_pixelstore_attrib *packing, 27360909388ab136d849d99eab49e782a53772a618fBrian Paul const GLvoid *image, 27460909388ab136d849d99eab49e782a53772a618fBrian Paul GLsizei width, GLsizei height, 27560909388ab136d849d99eab49e782a53772a618fBrian Paul GLenum format, GLenum type, 27660909388ab136d849d99eab49e782a53772a618fBrian Paul GLint img, GLint row, GLint column ) 27760909388ab136d849d99eab49e782a53772a618fBrian Paul{ 27860909388ab136d849d99eab49e782a53772a618fBrian Paul return _mesa_image_address(3, packing, image, width, height, 27960909388ab136d849d99eab49e782a53772a618fBrian Paul format, type, img, row, column); 28060909388ab136d849d99eab49e782a53772a618fBrian Paul} 28160909388ab136d849d99eab49e782a53772a618fBrian Paul 28260909388ab136d849d99eab49e782a53772a618fBrian Paul 28360909388ab136d849d99eab49e782a53772a618fBrian Paul 2846dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** 28517fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul * Compute the stride (in bytes) between image rows. 2866dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 2876dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param packing the pixelstore attributes 2886dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param width image width. 2896dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param format pixel format. 2906dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param type pixel data type. 2916dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 29217fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul * \return the stride in bytes for the given parameters, or -1 if error 293ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul */ 294ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian PaulGLint 295ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing, 296ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul GLint width, GLenum format, GLenum type ) 297ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul{ 29817fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul GLint bytesPerRow, remainder; 29917fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul 300bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(packing); 30117fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul 302ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul if (type == GL_BITMAP) { 303ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul if (packing->RowLength == 0) { 30417fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul bytesPerRow = (width + 7) / 8; 305ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul } 306ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul else { 30717fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul bytesPerRow = (packing->RowLength + 7) / 8; 308551b65f13754e6760e5c272ff86f8873c9c13e5cBrian Paul } 309ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul } 310ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul else { 311ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul /* Non-BITMAP data */ 312b7d076fc96ac27117421653a043d00a95f789d24Brian Paul const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); 313ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul if (bytesPerPixel <= 0) 314ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul return -1; /* error */ 315ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul if (packing->RowLength == 0) { 316fbbac25ad304e09a4cde52bd09b4940ac4785623Brian Paul bytesPerRow = bytesPerPixel * width; 317ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul } 318ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul else { 319fbbac25ad304e09a4cde52bd09b4940ac4785623Brian Paul bytesPerRow = bytesPerPixel * packing->RowLength; 320ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul } 321ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul } 32217fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul 32317fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul remainder = bytesPerRow % packing->Alignment; 32417fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul if (remainder > 0) { 32517fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul bytesPerRow += (packing->Alignment - remainder); 32617fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul } 32717fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul 32817fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul if (packing->Invert) { 32917fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul /* negate the bytes per row (negative row stride) */ 33017fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul bytesPerRow = -bytesPerRow; 33117fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul } 33217fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul 33317fb7821d7cdc0ed211eaef013ee7798619a61d3Brian Paul return bytesPerRow; 334ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul} 335ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul 336ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul 337ae40595b6943d41dfad0e9b500d5db70b2ad8c6eBrian Paul/* 338d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul * Compute the stride between images in a 3D texture (in bytes) for the given 339d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul * pixel packing parameters and image width, format and type. 340d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul */ 341d488af5b34e390a9b81dac96053bd45f34ffffffBrian PaulGLint 342d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing, 343d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul GLint width, GLint height, 344d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul GLenum format, GLenum type ) 345d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul{ 346995456f9305593005f8466520314ee087f3d422aBrian Paul GLint bytesPerRow, bytesPerImage, remainder; 347995456f9305593005f8466520314ee087f3d422aBrian Paul 348bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(packing); 349d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul 350995456f9305593005f8466520314ee087f3d422aBrian Paul if (type == GL_BITMAP) { 351995456f9305593005f8466520314ee087f3d422aBrian Paul if (packing->RowLength == 0) { 352995456f9305593005f8466520314ee087f3d422aBrian Paul bytesPerRow = (width + 7) / 8; 353995456f9305593005f8466520314ee087f3d422aBrian Paul } 354995456f9305593005f8466520314ee087f3d422aBrian Paul else { 355995456f9305593005f8466520314ee087f3d422aBrian Paul bytesPerRow = (packing->RowLength + 7) / 8; 356995456f9305593005f8466520314ee087f3d422aBrian Paul } 357995456f9305593005f8466520314ee087f3d422aBrian Paul } 358995456f9305593005f8466520314ee087f3d422aBrian Paul else { 359d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); 360d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul 361d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul if (bytesPerPixel <= 0) 362d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul return -1; /* error */ 363d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul if (packing->RowLength == 0) { 364d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul bytesPerRow = bytesPerPixel * width; 365d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul } 366d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul else { 367d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul bytesPerRow = bytesPerPixel * packing->RowLength; 368d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul } 369995456f9305593005f8466520314ee087f3d422aBrian Paul } 370d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul 371995456f9305593005f8466520314ee087f3d422aBrian Paul remainder = bytesPerRow % packing->Alignment; 372995456f9305593005f8466520314ee087f3d422aBrian Paul if (remainder > 0) 373995456f9305593005f8466520314ee087f3d422aBrian Paul bytesPerRow += (packing->Alignment - remainder); 374d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul 375995456f9305593005f8466520314ee087f3d422aBrian Paul if (packing->ImageHeight == 0) 376995456f9305593005f8466520314ee087f3d422aBrian Paul bytesPerImage = bytesPerRow * height; 377995456f9305593005f8466520314ee087f3d422aBrian Paul else 378995456f9305593005f8466520314ee087f3d422aBrian Paul bytesPerImage = bytesPerRow * packing->ImageHeight; 379995456f9305593005f8466520314ee087f3d422aBrian Paul 380995456f9305593005f8466520314ee087f3d422aBrian Paul return bytesPerImage; 381d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul} 382d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul 383d488af5b34e390a9b81dac96053bd45f34ffffffBrian Paul 384116970154dc3bb148178e1a9fe38554fbbd133c8Brian Paul 385278e76832fc26678592368b7b89bfddc137e0e93Brian Paul/** 386278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * "Expand" a bitmap from 1-bit per pixel to 8-bits per pixel. 387278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * This is typically used to convert a bitmap into a GLubyte/pixel texture. 388278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * "On" bits will set texels to \p onValue. 389278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * "Off" bits will not modify texels. 390278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param width src bitmap width in pixels 391278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param height src bitmap height in pixels 392278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param unpack bitmap unpacking state 393278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param bitmap the src bitmap data 394278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param destBuffer start of dest buffer 395278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param destStride row stride in dest buffer 396278e76832fc26678592368b7b89bfddc137e0e93Brian Paul * \param onValue if bit is 1, set destBuffer pixel to this value 397278e76832fc26678592368b7b89bfddc137e0e93Brian Paul */ 398278e76832fc26678592368b7b89bfddc137e0e93Brian Paulvoid 399278e76832fc26678592368b7b89bfddc137e0e93Brian Paul_mesa_expand_bitmap(GLsizei width, GLsizei height, 400278e76832fc26678592368b7b89bfddc137e0e93Brian Paul const struct gl_pixelstore_attrib *unpack, 401278e76832fc26678592368b7b89bfddc137e0e93Brian Paul const GLubyte *bitmap, 402278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GLubyte *destBuffer, GLint destStride, 403278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GLubyte onValue) 404278e76832fc26678592368b7b89bfddc137e0e93Brian Paul{ 405278e76832fc26678592368b7b89bfddc137e0e93Brian Paul const GLubyte *srcRow = (const GLubyte *) 406278e76832fc26678592368b7b89bfddc137e0e93Brian Paul _mesa_image_address2d(unpack, bitmap, width, height, 407278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GL_COLOR_INDEX, GL_BITMAP, 0, 0); 408278e76832fc26678592368b7b89bfddc137e0e93Brian Paul const GLint srcStride = _mesa_image_row_stride(unpack, width, 409278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GL_COLOR_INDEX, GL_BITMAP); 410278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GLint row, col; 4110eb7b5c2a3f17d64e85247c1f4907ce20bc57a73Brian Paul GLubyte *dstRow = destBuffer; 412278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 413278e76832fc26678592368b7b89bfddc137e0e93Brian Paul for (row = 0; row < height; row++) { 414278e76832fc26678592368b7b89bfddc137e0e93Brian Paul const GLubyte *src = srcRow; 415278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 416278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (unpack->LsbFirst) { 417278e76832fc26678592368b7b89bfddc137e0e93Brian Paul /* Lsb first */ 418278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GLubyte mask = 1U << (unpack->SkipPixels & 0x7); 419278e76832fc26678592368b7b89bfddc137e0e93Brian Paul for (col = 0; col < width; col++) { 420278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 421278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (*src & mask) { 4220eb7b5c2a3f17d64e85247c1f4907ce20bc57a73Brian Paul dstRow[col] = onValue; 423278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 424278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 425278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (mask == 128U) { 426278e76832fc26678592368b7b89bfddc137e0e93Brian Paul src++; 427278e76832fc26678592368b7b89bfddc137e0e93Brian Paul mask = 1U; 428278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 429278e76832fc26678592368b7b89bfddc137e0e93Brian Paul else { 430278e76832fc26678592368b7b89bfddc137e0e93Brian Paul mask = mask << 1; 431278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 432278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 433278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 434278e76832fc26678592368b7b89bfddc137e0e93Brian Paul /* get ready for next row */ 435278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (mask != 1) 436278e76832fc26678592368b7b89bfddc137e0e93Brian Paul src++; 437278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 438278e76832fc26678592368b7b89bfddc137e0e93Brian Paul else { 439278e76832fc26678592368b7b89bfddc137e0e93Brian Paul /* Msb first */ 440278e76832fc26678592368b7b89bfddc137e0e93Brian Paul GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); 441278e76832fc26678592368b7b89bfddc137e0e93Brian Paul for (col = 0; col < width; col++) { 442278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 443278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (*src & mask) { 4440eb7b5c2a3f17d64e85247c1f4907ce20bc57a73Brian Paul dstRow[col] = onValue; 445278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 446278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 447278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (mask == 1U) { 448278e76832fc26678592368b7b89bfddc137e0e93Brian Paul src++; 449278e76832fc26678592368b7b89bfddc137e0e93Brian Paul mask = 128U; 450278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 451278e76832fc26678592368b7b89bfddc137e0e93Brian Paul else { 452278e76832fc26678592368b7b89bfddc137e0e93Brian Paul mask = mask >> 1; 453278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 454278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 455278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 456278e76832fc26678592368b7b89bfddc137e0e93Brian Paul /* get ready for next row */ 457278e76832fc26678592368b7b89bfddc137e0e93Brian Paul if (mask != 128) 458278e76832fc26678592368b7b89bfddc137e0e93Brian Paul src++; 459278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } 460278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 461278e76832fc26678592368b7b89bfddc137e0e93Brian Paul srcRow += srcStride; 4620eb7b5c2a3f17d64e85247c1f4907ce20bc57a73Brian Paul dstRow += destStride; 463278e76832fc26678592368b7b89bfddc137e0e93Brian Paul } /* row */ 464278e76832fc26678592368b7b89bfddc137e0e93Brian Paul} 465278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 466278e76832fc26678592368b7b89bfddc137e0e93Brian Paul 4674084e3c215d4db6370422fc718217bade7445618Brian Paul 46832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul 46932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul/** 47032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * Convert an array of RGBA colors from one datatype to another. 4714bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul * NOTE: src may equal dst. In that case, we use a temporary buffer. 47232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul */ 47332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paulvoid 47432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul_mesa_convert_colors(GLenum srcType, const GLvoid *src, 47532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLenum dstType, GLvoid *dst, 47632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint count, const GLubyte mask[]) 47732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul{ 4781614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul GLuint *tempBuffer; 4794bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLboolean useTemp = (src == dst); 4804bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul 4811614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul tempBuffer = malloc(count * MAX_PIXEL_BYTES); 4821614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul if (!tempBuffer) 4831614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul return; 4841614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul 485bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(srcType != dstType); 48632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul 48732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul switch (srcType) { 48832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul case GL_UNSIGNED_BYTE: 48932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (dstType == GL_UNSIGNED_SHORT) { 4904bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; 4914bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst); 49232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint i; 49332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul for (i = 0; i < count; i++) { 49432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (!mask || mask[i]) { 4954bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]); 4964bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]); 4974bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]); 4984bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]); 49932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 50032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5014bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul if (useTemp) 502c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); 50332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 50432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul else { 5054bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; 5064bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst); 50732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint i; 508bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(dstType == GL_FLOAT); 50932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul for (i = 0; i < count; i++) { 51032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (!mask || mask[i]) { 5114bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]); 5124bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]); 5134bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]); 5144bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]); 51532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 51632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5174bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul if (useTemp) 518c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); 51932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 52032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul break; 52132a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul case GL_UNSIGNED_SHORT: 52232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (dstType == GL_UNSIGNED_BYTE) { 5234bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLushort (*src2)[4] = (const GLushort (*)[4]) src; 5244bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); 52532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint i; 52632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul for (i = 0; i < count; i++) { 52732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (!mask || mask[i]) { 5284bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]); 5294bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]); 5304bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]); 5314bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]); 53232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 53332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5344bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul if (useTemp) 535c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); 53632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 53732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul else { 5384bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLushort (*src2)[4] = (const GLushort (*)[4]) src; 5394bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst); 54032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint i; 541bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(dstType == GL_FLOAT); 54232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul for (i = 0; i < count; i++) { 54332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (!mask || mask[i]) { 5444bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]); 5454bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]); 5464bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]); 5474bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]); 54832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 54932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5504bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul if (useTemp) 551c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); 55232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 55332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul break; 55432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul case GL_FLOAT: 55532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (dstType == GL_UNSIGNED_BYTE) { 5564bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; 5574bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); 55832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint i; 55932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul for (i = 0; i < count; i++) { 56081a86aea4f0990a1b8795f9e00e7a6c4ba368281Dave Airlie if (!mask || mask[i]) 56181a86aea4f0990a1b8795f9e00e7a6c4ba368281Dave Airlie _mesa_unclamped_float_rgba_to_ubyte(dst1[i], src4[i]); 56232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5634bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul if (useTemp) 564c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); 56532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 56632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul else { 5674bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; 5684bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst); 56932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul GLuint i; 570bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(dstType == GL_UNSIGNED_SHORT); 57132a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul for (i = 0; i < count; i++) { 57232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (!mask || mask[i]) { 5734bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]); 5744bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]); 5754bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]); 5764bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]); 57732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 57832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5794bb9f4115c4b1930a140da78feff953e80f8a4f5Brian Paul if (useTemp) 580c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); 58132a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 58232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul break; 58332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul default: 58432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors"); 58532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 5861614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul 5871614de4045c36ab6ec060e3bd0d1f3394d05b91eBrian Paul free(tempBuffer); 58832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul} 58932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul 59032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul 59132a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul 59232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul 5934084e3c215d4db6370422fc718217bade7445618Brian Paul/** 59432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * Perform basic clipping for glDrawPixels. The image's position and size 59532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * and the unpack SkipPixels and SkipRows are adjusted so that the image 59632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * region is entirely within the window and scissor bounds. 59732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * NOTE: this will only work when glPixelZoom is (1, 1) or (1, -1). 59832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * If Pixel.ZoomY is -1, *destY will be changed to be the first row which 59932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul * we'll actually write. Beforehand, *destY-1 is the first drawing row. 6004084e3c215d4db6370422fc718217bade7445618Brian Paul * 6014084e3c215d4db6370422fc718217bade7445618Brian Paul * \return GL_TRUE if image is ready for drawing or 6024084e3c215d4db6370422fc718217bade7445618Brian Paul * GL_FALSE if image was completely clipped away (draw nothing) 6034084e3c215d4db6370422fc718217bade7445618Brian Paul */ 6044084e3c215d4db6370422fc718217bade7445618Brian PaulGLboolean 605f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_clip_drawpixels(const struct gl_context *ctx, 6064084e3c215d4db6370422fc718217bade7445618Brian Paul GLint *destX, GLint *destY, 6074084e3c215d4db6370422fc718217bade7445618Brian Paul GLsizei *width, GLsizei *height, 6081ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul struct gl_pixelstore_attrib *unpack) 6094084e3c215d4db6370422fc718217bade7445618Brian Paul{ 61031aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg const struct gl_framebuffer *buffer = ctx->DrawBuffer; 6114084e3c215d4db6370422fc718217bade7445618Brian Paul 6121ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul if (unpack->RowLength == 0) { 6131ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul unpack->RowLength = *width; 6141ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul } 6151ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul 616bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(ctx->Pixel.ZoomX == 1.0F); 617bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F); 618e677da9e54e836609f94a3aaca27d68a0bacbb96Brian Paul 6194084e3c215d4db6370422fc718217bade7445618Brian Paul /* left clipping */ 6204084e3c215d4db6370422fc718217bade7445618Brian Paul if (*destX < buffer->_Xmin) { 6211ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul unpack->SkipPixels += (buffer->_Xmin - *destX); 6224084e3c215d4db6370422fc718217bade7445618Brian Paul *width -= (buffer->_Xmin - *destX); 6234084e3c215d4db6370422fc718217bade7445618Brian Paul *destX = buffer->_Xmin; 6244084e3c215d4db6370422fc718217bade7445618Brian Paul } 6254084e3c215d4db6370422fc718217bade7445618Brian Paul /* right clipping */ 6264084e3c215d4db6370422fc718217bade7445618Brian Paul if (*destX + *width > buffer->_Xmax) 6274084e3c215d4db6370422fc718217bade7445618Brian Paul *width -= (*destX + *width - buffer->_Xmax); 6284084e3c215d4db6370422fc718217bade7445618Brian Paul 6294084e3c215d4db6370422fc718217bade7445618Brian Paul if (*width <= 0) 6304084e3c215d4db6370422fc718217bade7445618Brian Paul return GL_FALSE; 6314084e3c215d4db6370422fc718217bade7445618Brian Paul 63232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (ctx->Pixel.ZoomY == 1.0F) { 63332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul /* bottom clipping */ 63432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (*destY < buffer->_Ymin) { 63532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul unpack->SkipRows += (buffer->_Ymin - *destY); 63632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul *height -= (buffer->_Ymin - *destY); 63732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul *destY = buffer->_Ymin; 63832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 63932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul /* top clipping */ 64032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (*destY + *height > buffer->_Ymax) 64132a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul *height -= (*destY + *height - buffer->_Ymax); 64232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 64332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul else { /* upside down */ 64432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul /* top clipping */ 64532a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (*destY > buffer->_Ymax) { 64632a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul unpack->SkipRows += (*destY - buffer->_Ymax); 64732a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul *height -= (*destY - buffer->_Ymax); 64832a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul *destY = buffer->_Ymax; 64932a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul } 65032a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul /* bottom clipping */ 65132a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul if (*destY - *height < buffer->_Ymin) 65232a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul *height -= (buffer->_Ymin - (*destY - *height)); 65332a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul /* adjust destY so it's the first row to write to */ 65432a966dad9c5c6309adafcb58050cd0f70c32bdeBrian Paul (*destY)--; 6554084e3c215d4db6370422fc718217bade7445618Brian Paul } 6564084e3c215d4db6370422fc718217bade7445618Brian Paul 6574084e3c215d4db6370422fc718217bade7445618Brian Paul if (*height <= 0) 6587aeaca33c331f70d507fc83583b13b8d9fc3e847Ben Skeggs return GL_FALSE; 6594084e3c215d4db6370422fc718217bade7445618Brian Paul 6604084e3c215d4db6370422fc718217bade7445618Brian Paul return GL_TRUE; 6614084e3c215d4db6370422fc718217bade7445618Brian Paul} 6624084e3c215d4db6370422fc718217bade7445618Brian Paul 6634084e3c215d4db6370422fc718217bade7445618Brian Paul 6644084e3c215d4db6370422fc718217bade7445618Brian Paul/** 6654084e3c215d4db6370422fc718217bade7445618Brian Paul * Perform clipping for glReadPixels. The image's window position 6661ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul * and size, and the pack skipPixels, skipRows and rowLength are adjusted 6671ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul * so that the image region is entirely within the window bounds. 6684084e3c215d4db6370422fc718217bade7445618Brian Paul * Note: this is different from _mesa_clip_drawpixels() in that the 6691ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul * scissor box is ignored, and we use the bounds of the current readbuffer 67055d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery * surface or the attached image. 6714084e3c215d4db6370422fc718217bade7445618Brian Paul * 672d44fbd3c9d976763ec1f4a8f0314f294be8c14f4Brian Paul * \return GL_TRUE if region to read is in bounds 673d44fbd3c9d976763ec1f4a8f0314f294be8c14f4Brian Paul * GL_FALSE if region is completely out of bounds (nothing to read) 6744084e3c215d4db6370422fc718217bade7445618Brian Paul */ 6754084e3c215d4db6370422fc718217bade7445618Brian PaulGLboolean 676f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_clip_readpixels(const struct gl_context *ctx, 6774084e3c215d4db6370422fc718217bade7445618Brian Paul GLint *srcX, GLint *srcY, 6784084e3c215d4db6370422fc718217bade7445618Brian Paul GLsizei *width, GLsizei *height, 6791ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul struct gl_pixelstore_attrib *pack) 6804084e3c215d4db6370422fc718217bade7445618Brian Paul{ 68131aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg const struct gl_framebuffer *buffer = ctx->ReadBuffer; 68255d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery struct gl_renderbuffer *rb = buffer->_ColorReadBuffer; 68355d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery GLsizei clip_width; 68455d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery GLsizei clip_height; 68555d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery 68655d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery if (rb) { 68755d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery clip_width = rb->Width; 68855d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery clip_height = rb->Height; 68955d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery } else { 69055d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery clip_width = buffer->Width; 69155d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery clip_height = buffer->Height; 69255d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery } 69355d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery 6944084e3c215d4db6370422fc718217bade7445618Brian Paul 6951ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul if (pack->RowLength == 0) { 6961ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul pack->RowLength = *width; 6971ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul } 6981ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul 6994084e3c215d4db6370422fc718217bade7445618Brian Paul /* left clipping */ 7004084e3c215d4db6370422fc718217bade7445618Brian Paul if (*srcX < 0) { 7011ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul pack->SkipPixels += (0 - *srcX); 7024084e3c215d4db6370422fc718217bade7445618Brian Paul *width -= (0 - *srcX); 7034084e3c215d4db6370422fc718217bade7445618Brian Paul *srcX = 0; 7044084e3c215d4db6370422fc718217bade7445618Brian Paul } 7054084e3c215d4db6370422fc718217bade7445618Brian Paul /* right clipping */ 70655d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery if (*srcX + *width > clip_width) 70755d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery *width -= (*srcX + *width - clip_width); 7084084e3c215d4db6370422fc718217bade7445618Brian Paul 7094084e3c215d4db6370422fc718217bade7445618Brian Paul if (*width <= 0) 7104084e3c215d4db6370422fc718217bade7445618Brian Paul return GL_FALSE; 7114084e3c215d4db6370422fc718217bade7445618Brian Paul 7124084e3c215d4db6370422fc718217bade7445618Brian Paul /* bottom clipping */ 7134084e3c215d4db6370422fc718217bade7445618Brian Paul if (*srcY < 0) { 7141ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul pack->SkipRows += (0 - *srcY); 7154084e3c215d4db6370422fc718217bade7445618Brian Paul *height -= (0 - *srcY); 7164084e3c215d4db6370422fc718217bade7445618Brian Paul *srcY = 0; 7174084e3c215d4db6370422fc718217bade7445618Brian Paul } 7184084e3c215d4db6370422fc718217bade7445618Brian Paul /* top clipping */ 71955d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery if (*srcY + *height > clip_height) 72055d56d34e0535baa2c7e1e1d8f1be11593a07fa8Nanley Chery *height -= (*srcY + *height - clip_height); 7214084e3c215d4db6370422fc718217bade7445618Brian Paul 7224084e3c215d4db6370422fc718217bade7445618Brian Paul if (*height <= 0) 7237aeaca33c331f70d507fc83583b13b8d9fc3e847Ben Skeggs return GL_FALSE; 7244084e3c215d4db6370422fc718217bade7445618Brian Paul 7254084e3c215d4db6370422fc718217bade7445618Brian Paul return GL_TRUE; 7264084e3c215d4db6370422fc718217bade7445618Brian Paul} 7274084e3c215d4db6370422fc718217bade7445618Brian Paul 728ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 729ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul/** 73003bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul * Do clipping for a glCopyTexSubImage call. 73103bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul * The framebuffer source region might extend outside the framebuffer 73203bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul * bounds. Clip the source region against the framebuffer bounds and 73303bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul * adjust the texture/dest position and size accordingly. 73403bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul * 73503bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul * \return GL_FALSE if region is totally clipped, GL_TRUE otherwise. 73603bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul */ 73703bafd1f9fa000abdb794b2ae344a68840c83201Brian PaulGLboolean 738f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_clip_copytexsubimage(const struct gl_context *ctx, 73903bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul GLint *destX, GLint *destY, 74003bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul GLint *srcX, GLint *srcY, 74103bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul GLsizei *width, GLsizei *height) 74203bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul{ 74303bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul const struct gl_framebuffer *fb = ctx->ReadBuffer; 74403bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul const GLint srcX0 = *srcX, srcY0 = *srcY; 74503bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul 746d01c44aacaeabe1dd187163f9e204f40401698bcEric Anholt if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height, 74703bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul srcX, srcY, width, height)) { 74803bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul *destX = *destX + *srcX - srcX0; 74903bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul *destY = *destY + *srcY - srcY0; 75003bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul 75103bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul return GL_TRUE; 75203bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul } 75303bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul else { 75403bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul return GL_FALSE; 75503bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul } 75603bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul} 75703bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul 75803bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul 75903bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul 76003bafd1f9fa000abdb794b2ae344a68840c83201Brian Paul/** 761ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * Clip the rectangle defined by (x, y, width, height) against the bounds 762ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * specified by [xmin, xmax) and [ymin, ymax). 763ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise. 764ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul */ 765ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian PaulGLboolean 766ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul_mesa_clip_to_region(GLint xmin, GLint ymin, 767ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul GLint xmax, GLint ymax, 768ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul GLint *x, GLint *y, 769ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul GLsizei *width, GLsizei *height ) 770ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul{ 771ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul /* left clipping */ 772ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul if (*x < xmin) { 773ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul *width -= (xmin - *x); 774ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul *x = xmin; 775ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul } 776ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 777ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul /* right clipping */ 778ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul if (*x + *width > xmax) 779aa09e0a1d532d0de2e094957d0509a7f60ebeafaEric Anholt *width -= (*x + *width - xmax); 780ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 781ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul if (*width <= 0) 782ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul return GL_FALSE; 783ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 784ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul /* bottom (or top) clipping */ 785ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul if (*y < ymin) { 786ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul *height -= (ymin - *y); 787ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul *y = ymin; 788ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul } 789ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 790ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul /* top (or bottom) clipping */ 791ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul if (*y + *height > ymax) 792aa09e0a1d532d0de2e094957d0509a7f60ebeafaEric Anholt *height -= (*y + *height - ymax); 793ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 794ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul if (*height <= 0) 795ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul return GL_FALSE; 796ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul 797ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul return GL_TRUE; 798ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul} 799727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 800727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 801727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul/** 802727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * Clip dst coords against Xmax (or Ymax). 803727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 8049520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 805727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paulclip_right_or_top(GLint *srcX0, GLint *srcX1, 806727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLint *dstX0, GLint *dstX1, 807727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLint maxValue) 808727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul{ 809727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLfloat t, bias; 810727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 811727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstX1 > maxValue) { 812727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* X1 outside right edge */ 813bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX0 < maxValue); /* X0 should be inside right edge */ 814727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0); 815727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* chop off [t, 1] part */ 816bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(t >= 0.0 && t <= 1.0); 817727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *dstX1 = maxValue; 818b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; 819727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); 820727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul } 821727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul else if (*dstX0 > maxValue) { 822727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* X0 outside right edge */ 823bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX1 < maxValue); /* X1 should be inside right edge */ 824727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1); 825727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* chop off [t, 1] part */ 826bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(t >= 0.0 && t <= 1.0); 827727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *dstX0 = maxValue; 828b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F; 829727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); 830727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul } 831727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul} 832727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 833727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 834727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul/** 835727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * Clip dst coords against Xmin (or Ymin). 836727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 8379520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 838727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paulclip_left_or_bottom(GLint *srcX0, GLint *srcX1, 839727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLint *dstX0, GLint *dstX1, 840727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLint minValue) 841727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul{ 842727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLfloat t, bias; 843727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 844727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstX0 < minValue) { 845727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* X0 outside left edge */ 846bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX1 > minValue); /* X1 should be inside left edge */ 847727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0); 848727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* chop off [0, t] part */ 849bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(t >= 0.0 && t <= 1.0); 850727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *dstX0 = minValue; 851d1b929a13713e740c06e3abc8666fe56b513a41aMarek Olšák bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; 852727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); 853727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul } 854727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul else if (*dstX1 < minValue) { 855727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* X1 outside left edge */ 856bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX0 > minValue); /* X0 should be inside left edge */ 857727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1); 858727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* chop off [0, t] part */ 859bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(t >= 0.0 && t <= 1.0); 860727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *dstX1 = minValue; 861d1b929a13713e740c06e3abc8666fe56b513a41aMarek Olšák bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F; 862727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); 863727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul } 864727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul} 865727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 866727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 867727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul/** 868727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * Do clipping of blit src/dest rectangles. 869727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * The dest rect is clipped against both the buffer bounds and scissor bounds. 870727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * The src rect is just clipped against the buffer bounds. 871727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * 872727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * When either the src or dest rect is clipped, the other is also clipped 873727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * proportionately! 874727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * 875727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * Note that X0 need not be less than X1 (same for Y) for either the source 876727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * and dest rects. That makes the clipping a little trickier. 877727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * 878727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped 879727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 880727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian PaulGLboolean 881f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_clip_blit(struct gl_context *ctx, 882e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const struct gl_framebuffer *readFb, 883e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const struct gl_framebuffer *drawFb, 884727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, 885727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1) 886727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul{ 887727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul const GLint srcXmin = 0; 888e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const GLint srcXmax = readFb->Width; 889727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul const GLint srcYmin = 0; 890e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const GLint srcYmax = readFb->Height; 891727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 892727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* these include scissor bounds */ 893e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const GLint dstXmin = drawFb->_Xmin; 894e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const GLint dstXmax = drawFb->_Xmax; 895e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const GLint dstYmin = drawFb->_Ymin; 896e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand const GLint dstYmax = drawFb->_Ymax; 897727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 898727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* 899727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul printf("PreClipX: src: %d .. %d dst: %d .. %d\n", 900727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcX0, *srcX1, *dstX0, *dstX1); 901727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul printf("PreClipY: src: %d .. %d dst: %d .. %d\n", 902727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcY0, *srcY1, *dstY0, *dstY1); 903727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 904727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 905727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* trivial rejection tests */ 906727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstX0 == *dstX1) 907727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; /* no width */ 908727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstX0 <= dstXmin && *dstX1 <= dstXmin) 909727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; /* totally out (left) of bounds */ 910727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstX0 >= dstXmax && *dstX1 >= dstXmax) 911727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; /* totally out (right) of bounds */ 912727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 913727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstY0 == *dstY1) 914727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 915727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstY0 <= dstYmin && *dstY1 <= dstYmin) 916727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 917727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*dstY0 >= dstYmax && *dstY1 >= dstYmax) 918727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 919727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 920727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*srcX0 == *srcX1) 921727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 922727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*srcX0 <= srcXmin && *srcX1 <= srcXmin) 923727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 924727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*srcX0 >= srcXmax && *srcX1 >= srcXmax) 925727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 926727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 927727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*srcY0 == *srcY1) 928727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 929727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*srcY0 <= srcYmin && *srcY1 <= srcYmin) 930727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 931727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (*srcY0 >= srcYmax && *srcY1 >= srcYmax) 932727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_FALSE; 933727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 934727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* 935727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * dest clip 936727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 937727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax); 938727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax); 939727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin); 940727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin); 941727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 942727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* 943727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul * src clip (just swap src/dst values from above) 944727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 945727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax); 946727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax); 947727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin); 948727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin); 949727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 950727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul /* 951727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul printf("PostClipX: src: %d .. %d dst: %d .. %d\n", 952727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcX0, *srcX1, *dstX0, *dstX1); 953727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul printf("PostClipY: src: %d .. %d dst: %d .. %d\n", 954727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul *srcY0, *srcY1, *dstY0, *dstY1); 955727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul */ 956727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 957bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX0 >= dstXmin); 958bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX0 <= dstXmax); 959bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX1 >= dstXmin); 960bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstX1 <= dstXmax); 961bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner 962bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstY0 >= dstYmin); 963bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstY0 <= dstYmax); 964bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstY1 >= dstYmin); 965bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*dstY1 <= dstYmax); 966bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner 967bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcX0 >= srcXmin); 968bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcX0 <= srcXmax); 969bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcX1 >= srcXmin); 970bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcX1 <= srcXmax); 971bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner 972bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcY0 >= srcYmin); 973bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcY0 <= srcYmax); 974bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcY1 >= srcYmin); 975bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner assert(*srcY1 <= srcYmax); 976727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul 977727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul return GL_TRUE; 978727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul} 9790ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie 9800ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie/** 9810ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie * Swap the bytes in a 2D image. 9820ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie * 9830ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie * using the packing information this swaps the bytes 9840ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie * according to the format and type of data being input. 9850ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie * It takes into a/c various packing parameters like 9860ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie * Alignment and RowLength. 9870ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie */ 9880ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlievoid 9890ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie_mesa_swap_bytes_2d_image(GLenum format, GLenum type, 9900ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie const struct gl_pixelstore_attrib *packing, 9910ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie GLsizei width, GLsizei height, 9920ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie GLvoid *dst, const GLvoid *src) 9930ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie{ 9940ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie GLint swapSize = _mesa_sizeof_packed_type(type); 9950ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie 9960ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie assert(packing->SwapBytes); 9970ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie 9980ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie if (swapSize == 2 || swapSize == 4) { 9990ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; 10000ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie int stride = _mesa_image_row_stride(packing, width, format, type); 10010ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie int row; 10020ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie uint8_t *dstrow; 10030ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie const uint8_t *srcrow; 10040ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie assert(swapsPerPixel > 0); 10050ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); 10060ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie dstrow = dst; 10070ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie srcrow = src; 10080ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie for (row = 0; row < height; row++) { 10090ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie if (swapSize == 2) 10100ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie swap2_copy((GLushort *)dstrow, (GLushort *)srcrow, width * swapsPerPixel); 10110ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie else if (swapSize == 4) 10120ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie swap4_copy((GLuint *)dstrow, (GLuint *)srcrow, width * swapsPerPixel); 10130ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie dstrow += stride; 10140ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie srcrow += stride; 10150ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie } 10160ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie } 10170ad3a475ef81dad3baf607d749b91dfa1700ca23Dave Airlie} 1018