538 lines
22 KiB
C
538 lines
22 KiB
C
![]() |
/* $Id: texutil.c,v 1.1 2000/03/24 20:54:21 brianp Exp $ */
|
||
|
|
||
|
/*
|
||
|
* Mesa 3-D graphics library
|
||
|
* Version: 3.3
|
||
|
*
|
||
|
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
|
||
|
*
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||
|
* copy of this software and associated documentation files (the "Software"),
|
||
|
* to deal in the Software without restriction, including without limitation
|
||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||
|
* Software is furnished to do so, subject to the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice shall be included
|
||
|
* in all copies or substantial portions of the Software.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
|
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifdef PC_HEADER
|
||
|
#include "all.h"
|
||
|
#else
|
||
|
#include "glheader.h"
|
||
|
#include "image.h"
|
||
|
#include "mem.h"
|
||
|
#include "texutil.h"
|
||
|
#include "types.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Texture utilities which may be useful to device drivers.
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Convert texture image data into one a specific internal format.
|
||
|
* Input:
|
||
|
* dstFormat - the destination internal format
|
||
|
* dstWidth, dstHeight - the destination image size
|
||
|
* destImage - pointer to destination image buffer
|
||
|
* srcWidth, srcHeight - size of texture image
|
||
|
* srcFormat, srcType - format and datatype of source image
|
||
|
* srcImage - pointer to user's texture image
|
||
|
* packing - describes how user's texture image is packed.
|
||
|
* Return: pointer to resulting image data or NULL if error or out of memory
|
||
|
* or NULL if we can't process the given image format/type/internalFormat
|
||
|
* combination.
|
||
|
*
|
||
|
* Supported type conversions:
|
||
|
* srcFormat srcType dstFormat
|
||
|
* GL_INTENSITY GL_UNSIGNED_BYTE MESA_I8
|
||
|
* GL_LUMINANCE GL_UNSIGNED_BYTE MESA_L8
|
||
|
* GL_ALPHA GL_UNSIGNED_BYTE MESA_A8
|
||
|
* GL_COLOR_INDEX GL_UNSIGNED_BYTE MESA_C8
|
||
|
* GL_LUMINANCE_ALPHA GL_UNSIGNED_BYTE MESA_L8_A8
|
||
|
* GL_RGB GL_UNSIGNED_BYTE MESA_R5_G6_B5
|
||
|
* GL_RGB GL_UNSIGNED_SHORT_5_6_5 MESA_R5_G6_B5
|
||
|
* GL_RGBA GL_UNSIGNED_BYTE MESA_A4_R4_G4_B4
|
||
|
* GL_BGRA GL_UNSIGNED_SHORT_4_4_4_4_REV MESA_A4_R4_G4_B4
|
||
|
* GL_BGRA GL_UNSIGHED_SHORT_1_5_5_5_REV MESA_A1_R5_G5_B5
|
||
|
* GL_BGRA GL_UNSIGNED_INT_8_8_8_8_REV MESA_A8_R8_G8_B8
|
||
|
* more to be added for new drivers...
|
||
|
*
|
||
|
* Notes:
|
||
|
* Some hardware only supports texture images of specific aspect ratios.
|
||
|
* This code will do power-of-two image up-scaling if that's needed.
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
GLboolean
|
||
|
_mesa_convert_teximage(MesaIntTexFormat dstFormat,
|
||
|
GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
|
||
|
GLsizei srcWidth, GLsizei srcHeight,
|
||
|
GLenum srcFormat, GLenum srcType,
|
||
|
const GLvoid *srcImage,
|
||
|
const struct gl_pixelstore_attrib *packing)
|
||
|
{
|
||
|
const GLint wScale = dstWidth / srcWidth; /* must be power of two */
|
||
|
const GLint hScale = dstHeight / srcHeight; /* must be power of two */
|
||
|
ASSERT(dstWidth >= srcWidth);
|
||
|
ASSERT(dstHeight >= srcHeight);
|
||
|
ASSERT(dstImage);
|
||
|
ASSERT(srcImage);
|
||
|
ASSERT(packing);
|
||
|
|
||
|
switch (dstFormat) {
|
||
|
case MESA_I8:
|
||
|
case MESA_L8:
|
||
|
case MESA_A8:
|
||
|
case MESA_C8:
|
||
|
if (srcType != GL_UNSIGNED_BYTE ||
|
||
|
((srcFormat != GL_INTENSITY) &&
|
||
|
(srcFormat != GL_LUMINANCE) &&
|
||
|
(srcFormat != GL_ALPHA) &&
|
||
|
(srcFormat != GL_COLOR_INDEX))) {
|
||
|
/* bad internal format / srcFormat combination */
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
else {
|
||
|
/* store as 8-bit texels */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
/* no scaling needed - fast case */
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLubyte *dst = (GLubyte *) dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
MEMCPY(dst, src, dstWidth * sizeof(GLubyte));
|
||
|
dst += dstWidth;
|
||
|
src += srcStride;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLubyte *dst = (GLubyte *) dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
dst[col] = src[col / wScale];
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MESA_L8_A8:
|
||
|
if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
else {
|
||
|
/* store as 16-bit texels */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row, col;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
GLubyte alpha = src[col * 2 + 0];
|
||
|
GLubyte luminance = src[col * 2 + 1];
|
||
|
dst[col] = ((GLushort) luminance << 8) | alpha;
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
src += srcStride;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row, col;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
GLint srcCol = col / wScale;
|
||
|
GLubyte alpha = src[srcCol * 2 + 0];
|
||
|
GLubyte luminance = src[srcCol * 2 + 1];
|
||
|
dst[col] = ((GLushort) luminance << 8) | alpha;
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
src += srcStride;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MESA_R5_G6_B5:
|
||
|
if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
|
||
|
/* special, optimized case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
MEMCPY(dst, src, dstWidth * sizeof(GLushort));
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLushort *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
dst[col] = src[col / wScale];
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
|
||
|
/* general case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint col, col3;
|
||
|
for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
|
||
|
GLubyte r = src[col3 + 0];
|
||
|
GLubyte g = src[col3 + 1];
|
||
|
GLubyte b = src[col3 + 2];
|
||
|
dst[col] = ((r & 0xf8) << 8)
|
||
|
| ((g & 0xfc) << 3)
|
||
|
| ((b & 0xf8) >> 3);
|
||
|
}
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
GLint col3 = (col / wScale) * 3;
|
||
|
GLubyte r = src[col3 + 0];
|
||
|
GLubyte g = src[col3 + 1];
|
||
|
GLubyte b = src[col3 + 2];
|
||
|
dst[col] = ((r & 0xf8) << 8)
|
||
|
| ((g & 0xfc) << 3)
|
||
|
| ((b & 0xf8) >> 3);
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* can't handle this srcFormat/srcType combination */
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MESA_A4_R4_G4_B4:
|
||
|
/* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
|
||
|
if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
|
||
|
/* special, optimized case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
MEMCPY(dst, src, dstWidth * sizeof(GLushort));
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLushort *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
dst[col] = src[col / wScale];
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
|
||
|
/* general case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint col, col4;
|
||
|
for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
|
||
|
GLubyte r = src[col4 + 0];
|
||
|
GLubyte g = src[col4 + 1];
|
||
|
GLubyte b = src[col4 + 2];
|
||
|
GLubyte a = src[col4 + 3];
|
||
|
dst[col] = ((a & 0xf0) << 8)
|
||
|
| ((r & 0xf0) << 4)
|
||
|
| ((g & 0xf0) )
|
||
|
| ((b & 0xf0) >> 4);
|
||
|
}
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
GLint col4 = (col / wScale) * 4;
|
||
|
GLubyte r = src[col4 + 0];
|
||
|
GLubyte g = src[col4 + 1];
|
||
|
GLubyte b = src[col4 + 2];
|
||
|
GLubyte a = src[col4 + 3];
|
||
|
dst[col] = ((a & 0xf0) << 8)
|
||
|
| ((r & 0xf0) << 4)
|
||
|
| ((g & 0xf0) )
|
||
|
| ((b & 0xf0) >> 4);
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* can't handle this format/srcType combination */
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MESA_A1_R5_G5_B5:
|
||
|
/* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
|
||
|
if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
|
||
|
/* special, optimized case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
MEMCPY(dst, src, dstWidth * sizeof(GLushort));
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLushort *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
dst[col] = src[col / wScale];
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
|
||
|
/* general case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint col, col4;
|
||
|
for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
|
||
|
GLubyte r = src[col4 + 0];
|
||
|
GLubyte g = src[col4 + 1];
|
||
|
GLubyte b = src[col4 + 2];
|
||
|
GLubyte a = src[col4 + 3];
|
||
|
dst[col] = ((a & 0x80) << 8)
|
||
|
| ((r & 0xf8) << 7)
|
||
|
| ((g & 0xf8) << 2)
|
||
|
| ((b & 0xf8) >> 3);
|
||
|
}
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
GLint col4 = (col / wScale) * 4;
|
||
|
GLubyte r = src[col4 + 0];
|
||
|
GLubyte g = src[col4 + 1];
|
||
|
GLubyte b = src[col4 + 2];
|
||
|
GLubyte a = src[col4 + 3];
|
||
|
dst[col] = ((a & 0x80) << 8)
|
||
|
| ((r & 0xf8) << 7)
|
||
|
| ((g & 0xf8) << 2)
|
||
|
| ((b & 0xf8) >> 3);
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* can't handle this source format/type combination */
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case MESA_A8_R8_G8_B8:
|
||
|
/* 32-bit texels */
|
||
|
if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV){
|
||
|
/* special, optimized case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLuint *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
MEMCPY(dst, src, dstWidth * sizeof(GLuint));
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLuint *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLuint *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
dst[col] = src[col / wScale];
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
|
||
|
/* general case */
|
||
|
if (wScale == 1 && hScale == 1) {
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
|
||
|
const GLint srcStride = _mesa_image_row_stride(packing,
|
||
|
srcWidth, srcFormat, srcType);
|
||
|
GLuint *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint col, col4;
|
||
|
for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
|
||
|
GLubyte r = src[col4 + 0];
|
||
|
GLubyte g = src[col4 + 1];
|
||
|
GLubyte b = src[col4 + 2];
|
||
|
GLubyte a = src[col4 + 3];
|
||
|
dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
|
||
|
}
|
||
|
src += srcStride;
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* must rescale image */
|
||
|
GLushort *dst = dstImage;
|
||
|
GLint row;
|
||
|
for (row = 0; row < dstHeight; row++) {
|
||
|
GLint srcRow = row / hScale;
|
||
|
const GLubyte *src = _mesa_image_address(packing, srcImage,
|
||
|
srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
|
||
|
GLint col;
|
||
|
for (col = 0; col < dstWidth; col++) {
|
||
|
GLint col4 = (col / wScale) * 4;
|
||
|
GLubyte r = src[col4 + 0];
|
||
|
GLubyte g = src[col4 + 1];
|
||
|
GLubyte b = src[col4 + 2];
|
||
|
GLubyte a = src[col4 + 3];
|
||
|
dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
|
||
|
}
|
||
|
dst += dstWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
/* can't handle this source format/type combination */
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
|
||
|
default:
|
||
|
/* unexpected internal format! */
|
||
|
return GL_FALSE;
|
||
|
}
|
||
|
return GL_TRUE;
|
||
|
}
|