📄 image.c
字号:
return GL_TRUE;
case GL_HALF_FLOAT_ARB:
return ctx->Extensions.ARB_half_float_pixel;
default:
return GL_FALSE;
}
case GL_RGB:
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
return GL_TRUE;
case GL_HALF_FLOAT_ARB:
return ctx->Extensions.ARB_half_float_pixel;
default:
return GL_FALSE;
}
case GL_BGR:
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
return GL_TRUE;
case GL_HALF_FLOAT_ARB:
return ctx->Extensions.ARB_half_float_pixel;
default:
return GL_FALSE;
}
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
return GL_TRUE;
case GL_HALF_FLOAT_ARB:
return ctx->Extensions.ARB_half_float_pixel;
default:
return GL_FALSE;
}
case GL_YCBCR_MESA:
if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
return GL_TRUE;
else
return GL_FALSE;
default:
; /* fall-through */
}
return GL_FALSE;
}
/**
* Return the address of a specific pixel in an image (1D, 2D or 3D).
*
* Pixel unpacking/packing parameters are observed according to \p packing.
*
* \param dimensions either 1, 2 or 3 to indicate dimensionality of image
* \param image starting address of image data
* \param width the image width
* \param height theimage height
* \param format the pixel format
* \param type the pixel data type
* \param packing the pixelstore attributes
* \param img which image in the volume (0 for 1D or 2D images)
* \param row row of pixel in the image (0 for 1D images)
* \param column column of pixel in the image
*
* \return address of pixel on success, or NULL on error.
*
* \sa gl_pixelstore_attrib.
*/
GLvoid *
_mesa_image_address( GLuint dimensions,
const struct gl_pixelstore_attrib *packing,
const GLvoid *image,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLint img, GLint row, GLint column )
{
GLint alignment; /* 1, 2 or 4 */
GLint pixels_per_row;
GLint rows_per_image;
GLint skiprows;
GLint skippixels;
GLint skipimages; /* for 3-D volume images */
GLubyte *pixel_addr;
ASSERT(dimensions >= 1 && dimensions <= 3);
alignment = packing->Alignment;
if (packing->RowLength > 0) {
pixels_per_row = packing->RowLength;
}
else {
pixels_per_row = width;
}
if (packing->ImageHeight > 0) {
rows_per_image = packing->ImageHeight;
}
else {
rows_per_image = height;
}
skippixels = packing->SkipPixels;
/* Note: SKIP_ROWS _is_ used for 1D images */
skiprows = packing->SkipRows;
/* Note: SKIP_IMAGES is only used for 3D images */
skipimages = (dimensions == 3) ? packing->SkipImages : 0;
if (type == GL_BITMAP) {
/* BITMAP data */
GLint comp_per_pixel; /* components per pixel */
GLint bytes_per_comp; /* bytes per component */
GLint bytes_per_row;
GLint bytes_per_image;
/* Compute bytes per component */
bytes_per_comp = _mesa_sizeof_packed_type( type );
if (bytes_per_comp < 0) {
return NULL;
}
/* Compute number of components per pixel */
comp_per_pixel = _mesa_components_in_format( format );
if (comp_per_pixel < 0) {
return NULL;
}
bytes_per_row = alignment
* CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
bytes_per_image = bytes_per_row * rows_per_image;
pixel_addr = (GLubyte *) image
+ (skipimages + img) * bytes_per_image
+ (skiprows + row) * bytes_per_row
+ (skippixels + column) / 8;
}
else {
/* Non-BITMAP data */
GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
GLint topOfImage;
bytes_per_pixel = _mesa_bytes_per_pixel( format, type );
/* The pixel type and format should have been error checked earlier */
assert(bytes_per_pixel > 0);
bytes_per_row = pixels_per_row * bytes_per_pixel;
remainder = bytes_per_row % alignment;
if (remainder > 0)
bytes_per_row += (alignment - remainder);
ASSERT(bytes_per_row % alignment == 0);
bytes_per_image = bytes_per_row * rows_per_image;
if (packing->Invert) {
/* set pixel_addr to the last row */
topOfImage = bytes_per_row * (height - 1);
bytes_per_row = -bytes_per_row;
}
else {
topOfImage = 0;
}
/* compute final pixel address */
pixel_addr = (GLubyte *) image
+ (skipimages + img) * bytes_per_image
+ topOfImage
+ (skiprows + row) * bytes_per_row
+ (skippixels + column) * bytes_per_pixel;
}
return (GLvoid *) pixel_addr;
}
GLvoid *
_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
const GLvoid *image,
GLsizei width,
GLenum format, GLenum type,
GLint column )
{
return _mesa_image_address(1, packing, image, width, 1,
format, type, 0, 0, column);
}
GLvoid *
_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
const GLvoid *image,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLint row, GLint column )
{
return _mesa_image_address(2, packing, image, width, height,
format, type, 0, row, column);
}
GLvoid *
_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
const GLvoid *image,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLint img, GLint row, GLint column )
{
return _mesa_image_address(3, packing, image, width, height,
format, type, img, row, column);
}
/**
* Compute the stride between image rows.
*
* \param packing the pixelstore attributes
* \param width image width.
* \param format pixel format.
* \param type pixel data type.
*
* \return the stride in bytes for the given parameters.
*
* Computes the number of bytes per pixel and row and compensates for alignment.
*
* \sa gl_pixelstore_attrib.
*/
GLint
_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
GLint width, GLenum format, GLenum type )
{
ASSERT(packing);
if (type == GL_BITMAP) {
/* BITMAP data */
GLint bytes;
if (packing->RowLength == 0) {
bytes = (width + 7) / 8;
}
else {
bytes = (packing->RowLength + 7) / 8;
}
if (packing->Invert) {
/* negate the bytes per row (negative row stride) */
bytes = -bytes;
}
return bytes;
}
else {
/* Non-BITMAP data */
const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
GLint bytesPerRow, remainder;
if (bytesPerPixel <= 0)
return -1; /* error */
if (packing->RowLength == 0) {
bytesPerRow = bytesPerPixel * width;
}
else {
bytesPerRow = bytesPerPixel * packing->RowLength;
}
remainder = bytesPerRow % packing->Alignment;
if (remainder > 0)
bytesPerRow += (packing->Alignment - remainder);
if (packing->Invert)
bytesPerRow = -bytesPerRow;
return bytesPerRow;
}
}
#if _HAVE_FULL_GL
/*
* Compute the stride between images in a 3D texture (in bytes) for the given
* pixel packing parameters and image width, format and type.
*/
GLint
_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
GLint width, GLint height,
GLenum format, GLenum type )
{
ASSERT(packing);
ASSERT(type != GL_BITMAP);
{
const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
GLint bytesPerRow, bytesPerImage, remainder;
if (bytesPerPixel <= 0)
return -1; /* error */
if (packing->RowLength == 0) {
bytesPerRow = bytesPerPixel * width;
}
else {
bytesPerRow = bytesPerPixel * packing->RowLength;
}
remainder = bytesPerRow % packing->Alignment;
if (remainder > 0)
bytesPerRow += (packing->Alignment - remainder);
if (packing->ImageHeight == 0)
bytesPerImage = bytesPerRow * height;
else
bytesPerImage = bytesPerRow * packing->ImageHeight;
return bytesPerImage;
}
}
/*
* Unpack a 32x32 pixel polygon stipple from user memory using the
* current pixel unpack settings.
*/
void
_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
const struct gl_pixelstore_attrib *unpacking )
{
GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap( 32, 32, pattern, unpacking );
if (ptrn) {
/* Convert pattern from GLubytes to GLuints and handle big/little
* endian differences
*/
GLubyte *p = ptrn;
GLint i;
for (i = 0; i < 32; i++) {
dest[i] = (p[0] << 24)
| (p[1] << 16)
| (p[2] << 8)
| (p[3] );
p += 4;
}
FREE(ptrn);
}
}
/*
* Pack polygon stipple into user memory given current pixel packing
* settings.
*/
void
_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
const struct gl_pixelstore_attrib *packing )
{
/* Convert pattern from GLuints to GLubytes to handle big/little
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -