📄 pixels.c
字号:
/*** $Id: pixels.c,v 1.4 2003/09/04 06:02:53 weiym Exp $** ** Port to MiniGUI by Wei Yongming (2001/10/03).** Copyright (C) 2001 ~ 2002 Wei Yongming.** Copyright (C) 2003 Feynman Software.**** SDL - Simple DirectMedia Layer** Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//* General (mostly internal) pixel/color manipulation routines for SDL */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "newgal.h"#include "sysvideo.h"#include "blit.h"#include "pixels_c.h"#include "RLEaccel_c.h"/* Helper functions *//* * Allocate a pixel format structure and fill it according to the given info. */GAL_PixelFormat *GAL_AllocFormat(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask){ GAL_PixelFormat *format; Uint32 mask; /* Allocate an empty pixel format structure */ format = malloc(sizeof(*format)); if ( format == NULL ) { GAL_OutOfMemory(); return(NULL); } memset(format, 0, sizeof(*format)); format->alpha = GAL_ALPHA_OPAQUE; /* Set up the format */ format->BitsPerPixel = bpp; format->BytesPerPixel = (bpp+7)/8; format->DitheredPalette = FALSE; switch (bpp) { case 1: /* Create the 2 color black-white palette */ format->palette = (GAL_Palette *)malloc( sizeof(GAL_Palette)); if ( format->palette == NULL ) { GAL_FreeFormat(format); GAL_OutOfMemory(); return(NULL); } (format->palette)->ncolors = 2; (format->palette)->colors = (GAL_Color *)malloc( (format->palette)->ncolors*sizeof(GAL_Color)); if ( (format->palette)->colors == NULL ) { GAL_FreeFormat(format); GAL_OutOfMemory(); return(NULL); } format->palette->colors[0].r = 0xFF; format->palette->colors[0].g = 0xFF; format->palette->colors[0].b = 0xFF; format->palette->colors[1].r = 0x00; format->palette->colors[1].g = 0x00; format->palette->colors[1].b = 0x00; format->Rloss = 8; format->Gloss = 8; format->Bloss = 8; format->Aloss = 8; format->Rshift = 0; format->Gshift = 0; format->Bshift = 0; format->Ashift = 0; format->Rmask = 0; format->Gmask = 0; format->Bmask = 0; format->Amask = 0; break; case 4: /* Create the 16 color VGA palette */ format->palette = (GAL_Palette *)malloc( sizeof(GAL_Palette)); if ( format->palette == NULL ) { GAL_FreeFormat(format); GAL_OutOfMemory(); return(NULL); } (format->palette)->ncolors = 16; (format->palette)->colors = (GAL_Color *)malloc( (format->palette)->ncolors*sizeof(GAL_Color)); if ( (format->palette)->colors == NULL ) { GAL_FreeFormat(format); GAL_OutOfMemory(); return(NULL); } /* Punt for now, will this ever be used? */ memset((format->palette)->colors, 0, (format->palette)->ncolors*sizeof(GAL_Color)); /* Palettized formats have no mask info */ format->Rloss = 8; format->Gloss = 8; format->Bloss = 8; format->Aloss = 8; format->Rshift = 0; format->Gshift = 0; format->Bshift = 0; format->Ashift = 0; format->Rmask = 0; format->Gmask = 0; format->Bmask = 0; format->Amask = 0; break; case 8: /* Create an empty 256 color palette */ format->palette = (GAL_Palette *)malloc( sizeof(GAL_Palette)); if ( format->palette == NULL ) { GAL_FreeFormat(format); GAL_OutOfMemory(); return(NULL); } (format->palette)->ncolors = 256; (format->palette)->colors = (GAL_Color *)malloc( (format->palette)->ncolors*sizeof(GAL_Color)); if ( (format->palette)->colors == NULL ) { GAL_FreeFormat(format); GAL_OutOfMemory(); return(NULL); } memset((format->palette)->colors, 0, (format->palette)->ncolors*sizeof(GAL_Color)); /* Palettized formats have no mask info */ format->Rloss = 8; format->Gloss = 8; format->Bloss = 8; format->Aloss = 8; format->Rshift = 0; format->Gshift = 0; format->Bshift = 0; format->Ashift = 0; format->Rmask = 0; format->Gmask = 0; format->Bmask = 0; format->Amask = 0; break; default: /* No palette, just packed pixel info */ format->palette = NULL; format->Rshift = 0; format->Rloss = 8; if ( Rmask ) { for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) ++format->Rshift; for ( ; (mask&0x01); mask >>= 1 ) --format->Rloss; } format->Gshift = 0; format->Gloss = 8; if ( Gmask ) { for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) ++format->Gshift; for ( ; (mask&0x01); mask >>= 1 ) --format->Gloss; } format->Bshift = 0; format->Bloss = 8; if ( Bmask ) { for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) ++format->Bshift; for ( ; (mask&0x01); mask >>= 1 ) --format->Bloss; } format->Ashift = 0; format->Aloss = 8; if ( Amask ) { for ( mask = Amask; !(mask&0x01); mask >>= 1 ) ++format->Ashift; for ( ; (mask&0x01); mask >>= 1 ) --format->Aloss; } format->Rmask = Rmask; format->Gmask = Gmask; format->Bmask = Bmask; format->Amask = Amask; break; } /* Calculate some standard bitmasks, if necessary * Note: This could conflict with an alpha mask, if given. */ if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) { /* R-G-B */ if ( bpp > 24 ) bpp = 24; format->Rloss = 8-(bpp/3); format->Gloss = 8-(bpp/3)-(bpp%3); format->Bloss = 8-(bpp/3); format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); format->Gshift = (bpp/3); format->Bshift = 0; format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift); format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift); format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift); } return(format);}GAL_PixelFormat *GAL_ReallocFormat(GAL_Surface *surface, int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask){ if ( surface->format ) { GAL_FreeFormat(surface->format); GAL_FormatChanged(surface); } surface->format = GAL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); return surface->format;}/* * Change any previous mappings from/to the new surface format */void GAL_FormatChanged(GAL_Surface *surface){ surface->format_version++; GAL_InvalidateMap(surface->map);}/* * Free a previously allocated format structure */void GAL_FreeFormat(GAL_PixelFormat *format){ if ( format ) { if ( format->palette ) { if ( format->palette->colors ) { free(format->palette->colors); } free(format->palette); } free(format); }}/* * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors */void GAL_DitherColors(GAL_Color *colors, int bpp){ int i; if(bpp != 8) return; /* only 8bpp supported right now */ for(i = 0; i < 256; i++) { int r, g, b; /* map each bit field to the full [0, 255] interval, so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ r = i & 0xe0; r |= r >> 3 | r >> 6; colors[i].r = r; g = (i << 3) & 0xe0; g |= g >> 3 | g >> 6; colors[i].g = g; b = i & 0x3; b |= b << 2; b |= b << 4; colors[i].b = b; }}Uint8 GAL_FindDitheredColor (int bpp, Uint8 r, Uint8 g, Uint8 b){ if (bpp != 8) return 0; /* only 8bpp supported right now */ r &= 0xe0; g &= 0xe0; g >>= 3; b &= 0xc0; b >>= 6; return r | g | b;}/* * Calculate the pad-aligned scanline width of a surface */Uint16 GAL_CalculatePitch(GAL_Surface *surface){ Uint16 pitch; /* Box should be 4-byte aligned for speed */ pitch = surface->w * surface->format->BytesPerPixel; switch (surface->format->BitsPerPixel) { case 1: pitch = (pitch+7)/8; break; case 4: pitch = (pitch+1)/2; break; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -