mutter/cogl/cogl/cogl-pixel-format.c

505 lines
11 KiB
C

/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
*
* 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 THE AUTHORS OR COPYRIGHT HOLDERS
* 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.
*
*
*/
#include "config.h"
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "cogl/cogl-pixel-format.h"
/* An entry to map CoglPixelFormats to their respective properties */
typedef struct _CoglPixelFormatInfo
{
CoglPixelFormat cogl_format;
const char *format_str;
int aligned; /* Aligned components? (-1 if n/a) */
uint8_t n_planes;
/* Per-plane information */
uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES]; /* Bytes per pixel */
} CoglPixelFormatInfo;
static const CoglPixelFormatInfo format_info_table[] = {
{
.cogl_format = COGL_PIXEL_FORMAT_ANY,
.format_str = "ANY",
.n_planes = 0,
.aligned = -1,
.bpp = { 0 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_A_8,
.format_str = "A_8",
.n_planes = 1,
.aligned = 1,
.bpp = { 1 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
.format_str = "RGB_565",
.n_planes = 1,
.aligned = 0,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
.format_str = "RGBA_4444",
.n_planes = 1,
.aligned = 0,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
.format_str = "RGBA_5551",
.n_planes = 1,
.aligned = 0,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_YUV,
.format_str = "YUV",
.n_planes = 1,
.aligned = -1,
.bpp = { 0 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_R_8,
.format_str = "R_8",
.n_planes = 1,
.aligned = 1,
.bpp = { 1 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_R_16,
.format_str = "R_16",
.n_planes = 1,
.aligned = 1,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
.format_str = "RG_88",
.n_planes = 1,
.aligned = 1,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RG_1616,
.format_str = "RG_1616",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_16161616,
.format_str = "RGBA_16161616",
.n_planes = 1,
.aligned = 1,
.bpp = { 8 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_16161616_PRE,
.format_str = "RGBA_16161616_PRE",
.n_planes = 1,
.aligned = 1,
.bpp = { 8 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
.format_str = "RGB_888",
.n_planes = 1,
.aligned = 1,
.bpp = { 3 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
.format_str = "BGR_888",
.n_planes = 1,
.aligned = 1,
.bpp = { 3 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBX_8888,
.format_str = "RGBX_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
.format_str = "RGBA_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRX_8888,
.format_str = "BGRX_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
.format_str = "BGRA_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_XRGB_8888,
.format_str = "XRGB_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
.format_str = "ARGB_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_XBGR_8888,
.format_str = "XBGR_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
.format_str = "ABGR_8888",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
.format_str = "RGBA_1010102",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
.format_str = "BGRA_1010102",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_XRGB_2101010,
.format_str = "XRGB_2101010",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
.format_str = "ARGB_2101010",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_XBGR_2101010,
.format_str = "XBGR_2101010",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
.format_str = "ABGR_2101010",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
.format_str = "RGBA_8888_PRE",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
.format_str = "BGRA_8888_PRE",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
.format_str = "ARGB_8888_PRE",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
.format_str = "ABGR_8888_PRE",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
.format_str = "RGBA_4444_PRE",
.n_planes = 1,
.aligned = 0,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
.format_str = "RGBA_5551_PRE",
.n_planes = 1,
.aligned = 0,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
.format_str = "RGBA_1010102_PRE",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
.format_str = "BGRA_1010102_PRE",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
.format_str = "ARGB_2101010_PRE",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
.format_str = "ABGR_2101010_PRE",
.n_planes = 1,
.aligned = 0,
.bpp = { 4 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBX_FP_16161616,
.format_str = "RGBX_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616,
.format_str = "RGBA_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRX_FP_16161616,
.format_str = "BGRX_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616,
.format_str = "BGRA_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_XRGB_FP_16161616,
.format_str = "ARGB_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616,
.format_str = "ARGB_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_XBGR_FP_16161616,
.format_str = "ABGR_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616,
.format_str = "ABGR_FP_16161616",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE,
.format_str = "RGBA_FP_16161616_PRE",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE,
.format_str = "BGRA_FP_16161616_PRE",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE,
.format_str = "ARGB_FP_16161616_PRE",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE,
.format_str = "ABGR_FP_16161616_PRE",
.n_planes = 1,
.bpp = { 8 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232,
.format_str = "RGBA_FP_32323232",
.n_planes = 1,
.bpp = { 16 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_32323232_PRE,
.format_str = "RGBA_FP_32323232_PRE",
.n_planes = 1,
.bpp = { 16 },
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
.format_str = "DEPTH_16",
.n_planes = 1,
.aligned = 1,
.bpp = { 2 },
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
.format_str = "DEPTH_24_STENCIL_8",
.n_planes = 1,
.aligned = 1,
.bpp = { 4 },
},
};
int
cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format,
int plane)
{
size_t i;
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
{
g_return_val_if_fail (plane < format_info_table[i].n_planes, 0);
return format_info_table[i].bpp[plane];
}
}
g_assert_not_reached ();
}
/* Note: this also refers to the mapping defined above for
* cogl_pixel_format_get_bytes_per_pixel() */
gboolean
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
{
int aligned = -1;
size_t i;
/* NB: currently checking whether the format components are aligned
* or not determines whether the format is endian dependent or not.
* In the future though we might consider adding formats with
* aligned components that are also endian independent. */
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
{
aligned = format_info_table[i].aligned;
break;
}
}
g_return_val_if_fail (aligned != -1, FALSE);
return aligned;
}
int
cogl_pixel_format_get_n_planes (CoglPixelFormat format)
{
size_t i;
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
return format_info_table[i].n_planes;
}
g_assert_not_reached ();
}
const char *
cogl_pixel_format_to_string (CoglPixelFormat format)
{
size_t i;
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
return format_info_table[i].format_str;
}
g_assert_not_reached ();
}