pixel.c revision cdc920a0
1cdc920a0Smrg/* 2cdc920a0Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3cdc920a0Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4cdc920a0Smrg * 5cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6cdc920a0Smrg * copy of this software and associated documentation files (the "Software"), 7cdc920a0Smrg * to deal in the Software without restriction, including without limitation 8cdc920a0Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the 10cdc920a0Smrg * Software is furnished to do so, subject to the following conditions: 11cdc920a0Smrg * 12cdc920a0Smrg * The above copyright notice including the dates of first publication and 13cdc920a0Smrg * either this permission notice or a reference to 14cdc920a0Smrg * http://oss.sgi.com/projects/FreeB/ 15cdc920a0Smrg * shall be included in all copies or substantial portions of the Software. 16cdc920a0Smrg * 17cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19cdc920a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20cdc920a0Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21cdc920a0Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22cdc920a0Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23cdc920a0Smrg * SOFTWARE. 24cdc920a0Smrg * 25cdc920a0Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc. 26cdc920a0Smrg * shall not be used in advertising or otherwise to promote the sale, use or 27cdc920a0Smrg * other dealings in this Software without prior written authorization from 28cdc920a0Smrg * Silicon Graphics, Inc. 29cdc920a0Smrg */ 30cdc920a0Smrg 31cdc920a0Smrg#include "packrender.h" 32cdc920a0Smrg 33cdc920a0Smrgstatic const GLubyte MsbToLsbTable[256] = { 34cdc920a0Smrg 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 35cdc920a0Smrg 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 36cdc920a0Smrg 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 37cdc920a0Smrg 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 38cdc920a0Smrg 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 39cdc920a0Smrg 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 40cdc920a0Smrg 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 41cdc920a0Smrg 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 42cdc920a0Smrg 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 43cdc920a0Smrg 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 44cdc920a0Smrg 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 45cdc920a0Smrg 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 46cdc920a0Smrg 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 47cdc920a0Smrg 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 48cdc920a0Smrg 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 49cdc920a0Smrg 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 50cdc920a0Smrg 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 51cdc920a0Smrg 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 52cdc920a0Smrg 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 53cdc920a0Smrg 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 54cdc920a0Smrg 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 55cdc920a0Smrg 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 56cdc920a0Smrg 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 57cdc920a0Smrg 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 58cdc920a0Smrg 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 59cdc920a0Smrg 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 60cdc920a0Smrg 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 61cdc920a0Smrg 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 62cdc920a0Smrg 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 63cdc920a0Smrg 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 64cdc920a0Smrg 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 65cdc920a0Smrg 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 66cdc920a0Smrg}; 67cdc920a0Smrg 68cdc920a0Smrgstatic const GLubyte LowBitsMask[9] = { 69cdc920a0Smrg 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 70cdc920a0Smrg}; 71cdc920a0Smrg 72cdc920a0Smrgstatic const GLubyte HighBitsMask[9] = { 73cdc920a0Smrg 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 74cdc920a0Smrg}; 75cdc920a0Smrg 76cdc920a0Smrg 77cdc920a0Smrg/* 78cdc920a0Smrg** Copy bitmap data from clients packed memory applying unpacking modes as the 79cdc920a0Smrg** data is transfered into the destImage buffer. Return in modes the 80cdc920a0Smrg** set of pixel modes that are to be done by the server. 81cdc920a0Smrg*/ 82cdc920a0Smrgstatic void 83cdc920a0SmrgFillBitmap(__GLXcontext * gc, GLint width, GLint height, 84cdc920a0Smrg GLenum format, const GLvoid * userdata, GLubyte * destImage) 85cdc920a0Smrg{ 86cdc920a0Smrg const __GLXattribute *state = gc->client_state_private; 87cdc920a0Smrg GLint rowLength = state->storeUnpack.rowLength; 88cdc920a0Smrg GLint alignment = state->storeUnpack.alignment; 89cdc920a0Smrg GLint skipPixels = state->storeUnpack.skipPixels; 90cdc920a0Smrg GLint skipRows = state->storeUnpack.skipRows; 91cdc920a0Smrg GLint lsbFirst = state->storeUnpack.lsbFirst; 92cdc920a0Smrg GLint elementsLeft, bitOffset, currentByte, nextByte, highBitMask; 93cdc920a0Smrg GLint lowBitMask, i; 94cdc920a0Smrg GLint components, groupsPerRow, rowSize, padding, elementsPerRow; 95cdc920a0Smrg const GLubyte *start, *iter; 96cdc920a0Smrg 97cdc920a0Smrg if (rowLength > 0) { 98cdc920a0Smrg groupsPerRow = rowLength; 99cdc920a0Smrg } 100cdc920a0Smrg else { 101cdc920a0Smrg groupsPerRow = width; 102cdc920a0Smrg } 103cdc920a0Smrg components = __glElementsPerGroup(format, GL_BITMAP); 104cdc920a0Smrg rowSize = (groupsPerRow * components + 7) >> 3; 105cdc920a0Smrg padding = (rowSize % alignment); 106cdc920a0Smrg if (padding) { 107cdc920a0Smrg rowSize += alignment - padding; 108cdc920a0Smrg } 109cdc920a0Smrg start = ((const GLubyte *) userdata) + skipRows * rowSize + 110cdc920a0Smrg ((skipPixels * components) >> 3); 111cdc920a0Smrg bitOffset = (skipPixels * components) & 7; 112cdc920a0Smrg highBitMask = LowBitsMask[8 - bitOffset]; 113cdc920a0Smrg lowBitMask = HighBitsMask[bitOffset]; 114cdc920a0Smrg elementsPerRow = width * components; 115cdc920a0Smrg for (i = 0; i < height; i++) { 116cdc920a0Smrg elementsLeft = elementsPerRow; 117cdc920a0Smrg iter = start; 118cdc920a0Smrg while (elementsLeft) { 119cdc920a0Smrg /* First retrieve low bits from current byte */ 120cdc920a0Smrg if (lsbFirst) { 121cdc920a0Smrg currentByte = MsbToLsbTable[iter[0]]; 122cdc920a0Smrg } 123cdc920a0Smrg else { 124cdc920a0Smrg currentByte = iter[0]; 125cdc920a0Smrg } 126cdc920a0Smrg if (bitOffset) { 127cdc920a0Smrg /* Need to read next byte to finish current byte */ 128cdc920a0Smrg if (elementsLeft > (8 - bitOffset)) { 129cdc920a0Smrg if (lsbFirst) { 130cdc920a0Smrg nextByte = MsbToLsbTable[iter[1]]; 131cdc920a0Smrg } 132cdc920a0Smrg else { 133cdc920a0Smrg nextByte = iter[1]; 134cdc920a0Smrg } 135cdc920a0Smrg currentByte = 136cdc920a0Smrg ((currentByte & highBitMask) << bitOffset) | 137cdc920a0Smrg ((nextByte & lowBitMask) >> (8 - bitOffset)); 138cdc920a0Smrg } 139cdc920a0Smrg else { 140cdc920a0Smrg currentByte = ((currentByte & highBitMask) << bitOffset); 141cdc920a0Smrg } 142cdc920a0Smrg } 143cdc920a0Smrg if (elementsLeft >= 8) { 144cdc920a0Smrg *destImage = currentByte; 145cdc920a0Smrg elementsLeft -= 8; 146cdc920a0Smrg } 147cdc920a0Smrg else { 148cdc920a0Smrg *destImage = currentByte & HighBitsMask[elementsLeft]; 149cdc920a0Smrg elementsLeft = 0; 150cdc920a0Smrg } 151cdc920a0Smrg destImage++; 152cdc920a0Smrg iter++; 153cdc920a0Smrg } 154cdc920a0Smrg start += rowSize; 155cdc920a0Smrg } 156cdc920a0Smrg} 157cdc920a0Smrg 158cdc920a0Smrg/* 159cdc920a0Smrg** Extract array from user's data applying all pixel store modes. 160cdc920a0Smrg** The internal packed array format used has LSB_FIRST = FALSE and 161cdc920a0Smrg** ALIGNMENT = 1. 162cdc920a0Smrg*/ 163cdc920a0Smrgvoid 164cdc920a0Smrg__glFillImage(__GLXcontext * gc, GLint dim, GLint width, GLint height, 165cdc920a0Smrg GLint depth, GLenum format, GLenum type, 166cdc920a0Smrg const GLvoid * userdata, GLubyte * newimage, GLubyte * modes) 167cdc920a0Smrg{ 168cdc920a0Smrg const __GLXattribute *state = gc->client_state_private; 169cdc920a0Smrg GLint rowLength = state->storeUnpack.rowLength; 170cdc920a0Smrg GLint imageHeight = state->storeUnpack.imageHeight; 171cdc920a0Smrg GLint alignment = state->storeUnpack.alignment; 172cdc920a0Smrg GLint skipPixels = state->storeUnpack.skipPixels; 173cdc920a0Smrg GLint skipRows = state->storeUnpack.skipRows; 174cdc920a0Smrg GLint skipImages = state->storeUnpack.skipImages; 175cdc920a0Smrg GLint swapBytes = state->storeUnpack.swapEndian; 176cdc920a0Smrg GLint components, elementSize, rowSize, padding, groupsPerRow, groupSize; 177cdc920a0Smrg GLint elementsPerRow, imageSize, rowsPerImage, h, i, j, k; 178cdc920a0Smrg const GLubyte *start, *iter, *itera, *iterb, *iterc; 179cdc920a0Smrg GLubyte *iter2; 180cdc920a0Smrg 181cdc920a0Smrg if (type == GL_BITMAP) { 182cdc920a0Smrg FillBitmap(gc, width, height, format, userdata, newimage); 183cdc920a0Smrg } 184cdc920a0Smrg else { 185cdc920a0Smrg components = __glElementsPerGroup(format, type); 186cdc920a0Smrg if (rowLength > 0) { 187cdc920a0Smrg groupsPerRow = rowLength; 188cdc920a0Smrg } 189cdc920a0Smrg else { 190cdc920a0Smrg groupsPerRow = width; 191cdc920a0Smrg } 192cdc920a0Smrg if (imageHeight > 0) { 193cdc920a0Smrg rowsPerImage = imageHeight; 194cdc920a0Smrg } 195cdc920a0Smrg else { 196cdc920a0Smrg rowsPerImage = height; 197cdc920a0Smrg } 198cdc920a0Smrg 199cdc920a0Smrg elementSize = __glBytesPerElement(type); 200cdc920a0Smrg groupSize = elementSize * components; 201cdc920a0Smrg if (elementSize == 1) 202cdc920a0Smrg swapBytes = 0; 203cdc920a0Smrg 204cdc920a0Smrg rowSize = groupsPerRow * groupSize; 205cdc920a0Smrg padding = (rowSize % alignment); 206cdc920a0Smrg if (padding) { 207cdc920a0Smrg rowSize += alignment - padding; 208cdc920a0Smrg } 209cdc920a0Smrg imageSize = rowSize * rowsPerImage; 210cdc920a0Smrg start = ((const GLubyte *) userdata) + skipImages * imageSize + 211cdc920a0Smrg skipRows * rowSize + skipPixels * groupSize; 212cdc920a0Smrg iter2 = newimage; 213cdc920a0Smrg elementsPerRow = width * components; 214cdc920a0Smrg 215cdc920a0Smrg if (swapBytes) { 216cdc920a0Smrg itera = start; 217cdc920a0Smrg for (h = 0; h < depth; h++) { 218cdc920a0Smrg iterb = itera; 219cdc920a0Smrg for (i = 0; i < height; i++) { 220cdc920a0Smrg iterc = iterb; 221cdc920a0Smrg for (j = 0; j < elementsPerRow; j++) { 222cdc920a0Smrg for (k = 1; k <= elementSize; k++) { 223cdc920a0Smrg iter2[k - 1] = iterc[elementSize - k]; 224cdc920a0Smrg } 225cdc920a0Smrg iter2 += elementSize; 226cdc920a0Smrg iterc += elementSize; 227cdc920a0Smrg } 228cdc920a0Smrg iterb += rowSize; 229cdc920a0Smrg } 230cdc920a0Smrg itera += imageSize; 231cdc920a0Smrg } 232cdc920a0Smrg } 233cdc920a0Smrg else { 234cdc920a0Smrg itera = start; 235cdc920a0Smrg for (h = 0; h < depth; h++) { 236cdc920a0Smrg if (rowSize == elementsPerRow * elementSize) { 237cdc920a0Smrg /* Ha! This is mondo easy! */ 238cdc920a0Smrg __GLX_MEM_COPY(iter2, itera, 239cdc920a0Smrg elementsPerRow * elementSize * height); 240cdc920a0Smrg iter2 += elementsPerRow * elementSize * height; 241cdc920a0Smrg } 242cdc920a0Smrg else { 243cdc920a0Smrg iter = itera; 244cdc920a0Smrg for (i = 0; i < height; i++) { 245cdc920a0Smrg __GLX_MEM_COPY(iter2, iter, elementsPerRow * elementSize); 246cdc920a0Smrg iter2 += elementsPerRow * elementSize; 247cdc920a0Smrg iter += rowSize; 248cdc920a0Smrg } 249cdc920a0Smrg } 250cdc920a0Smrg itera += imageSize; 251cdc920a0Smrg } 252cdc920a0Smrg } 253cdc920a0Smrg } 254cdc920a0Smrg 255cdc920a0Smrg /* Setup store modes that describe what we just did */ 256cdc920a0Smrg if (modes) { 257cdc920a0Smrg if (dim < 3) { 258cdc920a0Smrg (void) memcpy(modes, __glXDefaultPixelStore + 4, 20); 259cdc920a0Smrg } 260cdc920a0Smrg else { 261cdc920a0Smrg (void) memcpy(modes, __glXDefaultPixelStore + 0, 36); 262cdc920a0Smrg } 263cdc920a0Smrg } 264cdc920a0Smrg} 265cdc920a0Smrg 266cdc920a0Smrg/* 267cdc920a0Smrg** Empty a bitmap in LSB_FIRST=GL_FALSE and ALIGNMENT=4 format packing it 268cdc920a0Smrg** into the clients memory using the pixel store PACK modes. 269cdc920a0Smrg*/ 270cdc920a0Smrgstatic void 271cdc920a0SmrgEmptyBitmap(__GLXcontext * gc, GLint width, GLint height, 272cdc920a0Smrg GLenum format, const GLubyte * sourceImage, GLvoid * userdata) 273cdc920a0Smrg{ 274cdc920a0Smrg const __GLXattribute *state = gc->client_state_private; 275cdc920a0Smrg GLint rowLength = state->storePack.rowLength; 276cdc920a0Smrg GLint alignment = state->storePack.alignment; 277cdc920a0Smrg GLint skipPixels = state->storePack.skipPixels; 278cdc920a0Smrg GLint skipRows = state->storePack.skipRows; 279cdc920a0Smrg GLint lsbFirst = state->storePack.lsbFirst; 280cdc920a0Smrg GLint components, groupsPerRow, rowSize, padding, elementsPerRow; 281cdc920a0Smrg GLint sourceRowSize, sourcePadding, sourceSkip; 282cdc920a0Smrg GLubyte *start, *iter; 283cdc920a0Smrg GLint elementsLeft, bitOffset, currentByte, highBitMask, lowBitMask; 284cdc920a0Smrg GLint writeMask, i; 285cdc920a0Smrg GLubyte writeByte; 286cdc920a0Smrg 287cdc920a0Smrg components = __glElementsPerGroup(format, GL_BITMAP); 288cdc920a0Smrg if (rowLength > 0) { 289cdc920a0Smrg groupsPerRow = rowLength; 290cdc920a0Smrg } 291cdc920a0Smrg else { 292cdc920a0Smrg groupsPerRow = width; 293cdc920a0Smrg } 294cdc920a0Smrg 295cdc920a0Smrg rowSize = (groupsPerRow * components + 7) >> 3; 296cdc920a0Smrg padding = (rowSize % alignment); 297cdc920a0Smrg if (padding) { 298cdc920a0Smrg rowSize += alignment - padding; 299cdc920a0Smrg } 300cdc920a0Smrg sourceRowSize = (width * components + 7) >> 3; 301cdc920a0Smrg sourcePadding = (sourceRowSize % 4); 302cdc920a0Smrg if (sourcePadding) { 303cdc920a0Smrg sourceSkip = 4 - sourcePadding; 304cdc920a0Smrg } 305cdc920a0Smrg else { 306cdc920a0Smrg sourceSkip = 0; 307cdc920a0Smrg } 308cdc920a0Smrg start = ((GLubyte *) userdata) + skipRows * rowSize + 309cdc920a0Smrg ((skipPixels * components) >> 3); 310cdc920a0Smrg bitOffset = (skipPixels * components) & 7; 311cdc920a0Smrg highBitMask = LowBitsMask[8 - bitOffset]; 312cdc920a0Smrg lowBitMask = HighBitsMask[bitOffset]; 313cdc920a0Smrg elementsPerRow = width * components; 314cdc920a0Smrg for (i = 0; i < height; i++) { 315cdc920a0Smrg elementsLeft = elementsPerRow; 316cdc920a0Smrg iter = start; 317cdc920a0Smrg writeMask = highBitMask; 318cdc920a0Smrg writeByte = 0; 319cdc920a0Smrg while (elementsLeft) { 320cdc920a0Smrg /* Set up writeMask (to write to current byte) */ 321cdc920a0Smrg if (elementsLeft + bitOffset < 8) { 322cdc920a0Smrg /* Need to trim writeMask */ 323cdc920a0Smrg writeMask &= HighBitsMask[bitOffset + elementsLeft]; 324cdc920a0Smrg } 325cdc920a0Smrg 326cdc920a0Smrg if (lsbFirst) { 327cdc920a0Smrg currentByte = MsbToLsbTable[iter[0]]; 328cdc920a0Smrg } 329cdc920a0Smrg else { 330cdc920a0Smrg currentByte = iter[0]; 331cdc920a0Smrg } 332cdc920a0Smrg 333cdc920a0Smrg if (bitOffset) { 334cdc920a0Smrg writeByte |= (sourceImage[0] >> bitOffset); 335cdc920a0Smrg currentByte = (currentByte & ~writeMask) | 336cdc920a0Smrg (writeByte & writeMask); 337cdc920a0Smrg writeByte = (sourceImage[0] << (8 - bitOffset)); 338cdc920a0Smrg } 339cdc920a0Smrg else { 340cdc920a0Smrg currentByte = (currentByte & ~writeMask) | 341cdc920a0Smrg (sourceImage[0] & writeMask); 342cdc920a0Smrg } 343cdc920a0Smrg 344cdc920a0Smrg if (lsbFirst) { 345cdc920a0Smrg iter[0] = MsbToLsbTable[currentByte]; 346cdc920a0Smrg } 347cdc920a0Smrg else { 348cdc920a0Smrg iter[0] = currentByte; 349cdc920a0Smrg } 350cdc920a0Smrg 351cdc920a0Smrg if (elementsLeft >= 8) { 352cdc920a0Smrg elementsLeft -= 8; 353cdc920a0Smrg } 354cdc920a0Smrg else { 355cdc920a0Smrg elementsLeft = 0; 356cdc920a0Smrg } 357cdc920a0Smrg sourceImage++; 358cdc920a0Smrg iter++; 359cdc920a0Smrg writeMask = 0xff; 360cdc920a0Smrg } 361cdc920a0Smrg if (writeByte) { 362cdc920a0Smrg /* Some data left over that still needs writing */ 363cdc920a0Smrg writeMask &= lowBitMask; 364cdc920a0Smrg if (lsbFirst) { 365cdc920a0Smrg currentByte = MsbToLsbTable[iter[0]]; 366cdc920a0Smrg } 367cdc920a0Smrg else { 368cdc920a0Smrg currentByte = iter[0]; 369cdc920a0Smrg } 370cdc920a0Smrg currentByte = (currentByte & ~writeMask) | (writeByte & writeMask); 371cdc920a0Smrg if (lsbFirst) { 372cdc920a0Smrg iter[0] = MsbToLsbTable[currentByte]; 373cdc920a0Smrg } 374cdc920a0Smrg else { 375cdc920a0Smrg iter[0] = currentByte; 376cdc920a0Smrg } 377cdc920a0Smrg } 378cdc920a0Smrg start += rowSize; 379cdc920a0Smrg sourceImage += sourceSkip; 380cdc920a0Smrg } 381cdc920a0Smrg} 382cdc920a0Smrg 383cdc920a0Smrg/* 384cdc920a0Smrg** Insert array into user's data applying all pixel store modes. 385cdc920a0Smrg** The packed array format from the server is LSB_FIRST = FALSE, 386cdc920a0Smrg** SWAP_BYTES = the current pixel storage pack mode, and ALIGNMENT = 4. 387cdc920a0Smrg** Named __glEmptyImage() because it is the opposite of __glFillImage(). 388cdc920a0Smrg*/ 389cdc920a0Smrg/* ARGSUSED */ 390cdc920a0Smrgvoid 391cdc920a0Smrg__glEmptyImage(__GLXcontext * gc, GLint dim, GLint width, GLint height, 392cdc920a0Smrg GLint depth, GLenum format, GLenum type, 393cdc920a0Smrg const GLubyte * sourceImage, GLvoid * userdata) 394cdc920a0Smrg{ 395cdc920a0Smrg const __GLXattribute *state = gc->client_state_private; 396cdc920a0Smrg GLint rowLength = state->storePack.rowLength; 397cdc920a0Smrg GLint imageHeight = state->storePack.imageHeight; 398cdc920a0Smrg GLint alignment = state->storePack.alignment; 399cdc920a0Smrg GLint skipPixels = state->storePack.skipPixels; 400cdc920a0Smrg GLint skipRows = state->storePack.skipRows; 401cdc920a0Smrg GLint skipImages = state->storePack.skipImages; 402cdc920a0Smrg GLint components, elementSize, rowSize, padding, groupsPerRow, groupSize; 403cdc920a0Smrg GLint elementsPerRow, sourceRowSize, sourcePadding, h, i; 404cdc920a0Smrg GLint imageSize, rowsPerImage; 405cdc920a0Smrg GLubyte *start, *iter, *itera; 406cdc920a0Smrg 407cdc920a0Smrg if (type == GL_BITMAP) { 408cdc920a0Smrg EmptyBitmap(gc, width, height, format, sourceImage, userdata); 409cdc920a0Smrg } 410cdc920a0Smrg else { 411cdc920a0Smrg components = __glElementsPerGroup(format, type); 412cdc920a0Smrg if (rowLength > 0) { 413cdc920a0Smrg groupsPerRow = rowLength; 414cdc920a0Smrg } 415cdc920a0Smrg else { 416cdc920a0Smrg groupsPerRow = width; 417cdc920a0Smrg } 418cdc920a0Smrg if (imageHeight > 0) { 419cdc920a0Smrg rowsPerImage = imageHeight; 420cdc920a0Smrg } 421cdc920a0Smrg else { 422cdc920a0Smrg rowsPerImage = height; 423cdc920a0Smrg } 424cdc920a0Smrg elementSize = __glBytesPerElement(type); 425cdc920a0Smrg groupSize = elementSize * components; 426cdc920a0Smrg rowSize = groupsPerRow * groupSize; 427cdc920a0Smrg padding = (rowSize % alignment); 428cdc920a0Smrg if (padding) { 429cdc920a0Smrg rowSize += alignment - padding; 430cdc920a0Smrg } 431cdc920a0Smrg sourceRowSize = width * groupSize; 432cdc920a0Smrg sourcePadding = (sourceRowSize % 4); 433cdc920a0Smrg if (sourcePadding) { 434cdc920a0Smrg sourceRowSize += 4 - sourcePadding; 435cdc920a0Smrg } 436cdc920a0Smrg imageSize = sourceRowSize * rowsPerImage; 437cdc920a0Smrg start = ((GLubyte *) userdata) + skipImages * imageSize + 438cdc920a0Smrg skipRows * rowSize + skipPixels * groupSize; 439cdc920a0Smrg elementsPerRow = width * components; 440cdc920a0Smrg 441cdc920a0Smrg itera = start; 442cdc920a0Smrg for (h = 0; h < depth; h++) { 443cdc920a0Smrg if ((rowSize == sourceRowSize) && (sourcePadding == 0)) { 444cdc920a0Smrg /* Ha! This is mondo easy! */ 445cdc920a0Smrg __GLX_MEM_COPY(itera, sourceImage, 446cdc920a0Smrg elementsPerRow * elementSize * height); 447cdc920a0Smrg sourceImage += elementsPerRow * elementSize * height; 448cdc920a0Smrg } 449cdc920a0Smrg else { 450cdc920a0Smrg iter = itera; 451cdc920a0Smrg for (i = 0; i < height; i++) { 452cdc920a0Smrg __GLX_MEM_COPY(iter, sourceImage, 453cdc920a0Smrg elementsPerRow * elementSize); 454cdc920a0Smrg sourceImage += sourceRowSize; 455cdc920a0Smrg iter += rowSize; 456cdc920a0Smrg } 457cdc920a0Smrg } 458cdc920a0Smrg itera += imageSize; 459cdc920a0Smrg } 460cdc920a0Smrg } 461cdc920a0Smrg} 462