freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] arv-test 291c905: Initial commit - only C


From: Arvinder Bhathal
Subject: [freetype2] arv-test 291c905: Initial commit - only C
Date: Wed, 21 Jun 2017 00:30:52 -0400 (EDT)

branch: arv-test
commit 291c90597f7500201f8ce6778011d939d61846f8
Author: Arvinder Bhathal <address@hidden>
Commit: Arvinder Bhathal <address@hidden>

    Initial commit - only C
---
 glyphtest/main-2.c |  74 +++++
 glyphtest/main.c   |  74 +++++
 glyphtest/qdbmp.c  | 798 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 glyphtest/qdbmp.h  | 133 +++++++++
 4 files changed, 1079 insertions(+)

diff --git a/glyphtest/main-2.c b/glyphtest/main-2.c
new file mode 100644
index 0000000..0c84692
--- /dev/null
+++ b/glyphtest/main-2.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "qdbmp.h"
+
+int main() 
+{
+       // ft
+       FT_Library library;
+       FT_Face face;
+       FT_Bitmap bmp;
+       FT_UInt x, y, glyph_index;
+       FT_Byte byte;
+       BMP* qdbmp;
+       char filename[20];
+
+       if (FT_Init_FreeType(&library)) 
+       {
+               printf("Error: Library initialization\n");
+       }
+
+       if (FT_New_Face(library, 
"/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf", 0, &face)) 
+       {
+               printf("Error: Loading face\n");
+       }
+
+       // if (FT_Set_Char_Size(face, 0, 16*64, 96, 0))
+       // {
+       //      printf("Error: Setting character size\n");
+       // }
+
+       if (FT_Set_Pixel_Sizes(face, 0, 48))
+       {
+               printf("Error: Setting character size\n");
+       }
+
+       for (glyph_index = 65; glyph_index < 91; glyph_index++)
+       {
+               if (FT_Load_Char(face, glyph_index, FT_LOAD_RENDER)) 
+               {
+                       printf("Error: Loading characte.r\n");
+               }
+
+               bmp = face->glyph->bitmap;
+
+               // printf("Width: %u\n", bmp.width);
+               // printf("Height: %u\n", bmp.rows);
+               // printf("Num grays: %u\n", bmp.num_grays);
+               // printf("Pitch: %d\n", bmp.pitch);
+
+               qdbmp = BMP_Create(bmp.width,bmp.rows,24);
+               BMP_CHECK_ERROR(stdout, 1);
+
+               for (y = 0; y < bmp.rows; y++) 
+               {
+                       for (x = 0; x < bmp.width; x++)
+                       {
+                               byte = bmp.buffer[bmp.pitch * y + x];
+                               BMP_SetPixelRGB(qdbmp, x, y, byte, byte, byte);
+                               BMP_CHECK_ERROR(stdout, 1);
+                       }
+               }
+
+               sprintf(filename, "%d-2", glyph_index);
+
+               BMP_WriteFile(qdbmp, filename);
+               BMP_CHECK_ERROR(stdout, 1);
+
+       }
+
+       FT_Done_Face(face);
+       FT_Done_FreeType(library);
+       return 0;
+}
\ No newline at end of file
diff --git a/glyphtest/main.c b/glyphtest/main.c
new file mode 100644
index 0000000..cc1b60d
--- /dev/null
+++ b/glyphtest/main.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "qdbmp.h"
+
+int main() 
+{
+       // ft
+       FT_Library library;
+       FT_Face face;
+       FT_Bitmap bmp;
+       FT_UInt x, y, glyph_index;
+       FT_Byte byte;
+       BMP* qdbmp;
+       char filename[20];
+
+       if (FT_Init_FreeType(&library)) 
+       {
+               printf("Error: Library initialization\n");
+       }
+
+       if (FT_New_Face(library, 
"/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf", 0, &face)) 
+       {
+               printf("Error: Loading face\n");
+       }
+
+       // if (FT_Set_Char_Size(face, 0, 16*64, 96, 0))
+       // {
+       //      printf("Error: Setting character size\n");
+       // }
+
+       if (FT_Set_Pixel_Sizes(face, 0, 48))
+       {
+               printf("Error: Setting character size\n");
+       }
+
+       for (glyph_index = 65; glyph_index < 91; glyph_index++)
+       {
+               if (FT_Load_Char(face, glyph_index, FT_LOAD_RENDER)) 
+               {
+                       printf("Error: Loading characte.r\n");
+               }
+
+               bmp = face->glyph->bitmap;
+
+               // printf("Width: %u\n", bmp.width);
+               // printf("Height: %u\n", bmp.rows);
+               // printf("Num grays: %u\n", bmp.num_grays);
+               // printf("Pitch: %d\n", bmp.pitch);
+
+               qdbmp = BMP_Create(bmp.width,bmp.rows,24);
+               BMP_CHECK_ERROR(stdout, 1);
+
+               for (y = 0; y < bmp.rows; y++) 
+               {
+                       for (x = 0; x < bmp.width; x++)
+                       {
+                               byte = bmp.buffer[bmp.pitch * y + x];
+                               BMP_SetPixelRGB(qdbmp, x, y, byte, byte, byte);
+                               BMP_CHECK_ERROR(stdout, 1);
+                       }
+               }
+
+               sprintf(filename, "%d", glyph_index);
+
+               BMP_WriteFile(qdbmp, filename);
+               BMP_CHECK_ERROR(stdout, 1);
+
+       }
+
+       FT_Done_Face(face);
+       FT_Done_FreeType(library);
+       return 0;
+}
\ No newline at end of file
diff --git a/glyphtest/qdbmp.c b/glyphtest/qdbmp.c
new file mode 100755
index 0000000..fd13372
--- /dev/null
+++ b/glyphtest/qdbmp.c
@@ -0,0 +1,798 @@
+#include "qdbmp.h"
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Bitmap header */
+typedef struct _BMP_Header
+{
+       USHORT          Magic;                          /* Magic identifier: 
"BM" */
+       UINT            FileSize;                       /* Size of the BMP file 
in bytes */
+       USHORT          Reserved1;                      /* Reserved */
+       USHORT          Reserved2;                      /* Reserved */
+       UINT            DataOffset;                     /* Offset of image data 
relative to the file's start */
+       UINT            HeaderSize;                     /* Size of the header 
in bytes */
+       UINT            Width;                          /* Bitmap's width */
+       UINT            Height;                         /* Bitmap's height */
+       USHORT          Planes;                         /* Number of color 
planes in the bitmap */
+       USHORT          BitsPerPixel;           /* Number of bits per pixel */
+       UINT            CompressionType;        /* Compression type */
+       UINT            ImageDataSize;          /* Size of uncompressed image's 
data */
+       UINT            HPixelsPerMeter;        /* Horizontal resolution 
(pixels per meter) */
+       UINT            VPixelsPerMeter;        /* Vertical resolution (pixels 
per meter) */
+       UINT            ColorsUsed;                     /* Number of color 
indexes in the color table that are actually used by the bitmap */
+       UINT            ColorsRequired;         /* Number of color indexes that 
are required for displaying the bitmap */
+} BMP_Header;
+
+
+/* Private data structure */
+struct _BMP
+{
+       BMP_Header      Header;
+       UCHAR*          Palette;
+       UCHAR*          Data;
+};
+
+
+/* Holds the last error code */
+static BMP_STATUS BMP_LAST_ERROR_CODE = 0;
+
+
+/* Error description strings */
+static const char* BMP_ERROR_STRING[] =
+{
+       "",
+       "General error",
+       "Could not allocate enough memory to complete the operation",
+       "File input/output error",
+       "File not found",
+       "File is not a supported BMP variant (must be uncompressed 8, 24 or 32 
BPP)",
+       "File is not a valid BMP image",
+       "An argument is invalid or out of range",
+       "The requested action is not compatible with the BMP's type"
+};
+
+
+/* Size of the palette data for 8 BPP bitmaps */
+#define BMP_PALETTE_SIZE       ( 256 * 4 )
+
+
+
+/*********************************** Forward declarations 
**********************************/
+int            ReadHeader      ( BMP* bmp, FILE* f );
+int            WriteHeader     ( BMP* bmp, FILE* f );
+
+int            ReadUINT        ( UINT* x, FILE* f );
+int            ReadUSHORT      ( USHORT *x, FILE* f );
+
+int            WriteUINT       ( UINT x, FILE* f );
+int            WriteUSHORT     ( USHORT x, FILE* f );
+
+
+
+
+
+
+/*********************************** Public methods 
**********************************/
+
+
+/**************************************************************
+       Creates a blank BMP image with the specified dimensions
+       and bit depth.
+**************************************************************/
+BMP* BMP_Create( UINT width, UINT height, USHORT depth )
+{
+       BMP*    bmp;
+       int             bytes_per_pixel = depth >> 3;
+       UINT    bytes_per_row;
+
+       if ( height <= 0 || width <= 0 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+               return NULL;
+       }
+
+       if ( depth != 8 && depth != 24 && depth != 32 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED;
+               return NULL;
+       }
+
+
+       /* Allocate the bitmap data structure */
+       bmp = calloc( 1, sizeof( BMP ) );
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+
+       /* Set header' default values */
+       bmp->Header.Magic                               = 0x4D42;
+       bmp->Header.Reserved1                   = 0;
+       bmp->Header.Reserved2                   = 0;
+       bmp->Header.HeaderSize                  = 40;
+       bmp->Header.Planes                              = 1;
+       bmp->Header.CompressionType             = 0;
+       bmp->Header.HPixelsPerMeter             = 0;
+       bmp->Header.VPixelsPerMeter             = 0;
+       bmp->Header.ColorsUsed                  = 0;
+       bmp->Header.ColorsRequired              = 0;
+
+
+       /* Calculate the number of bytes used to store a single image row. This 
is always
+       rounded up to the next multiple of 4. */
+       bytes_per_row = width * bytes_per_pixel;
+       bytes_per_row += ( bytes_per_row % 4 ? 4 - bytes_per_row % 4 : 0 );
+
+
+       /* Set header's image specific values */
+       bmp->Header.Width                               = width;
+       bmp->Header.Height                              = height;
+       bmp->Header.BitsPerPixel                = depth;
+       bmp->Header.ImageDataSize               = bytes_per_row * height;
+       bmp->Header.FileSize                    = bmp->Header.ImageDataSize + 
54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 );
+       bmp->Header.DataOffset                  = 54 + ( depth == 8 ? 
BMP_PALETTE_SIZE : 0 );
+
+
+       /* Allocate palette */
+       if ( bmp->Header.BitsPerPixel == 8 )
+       {
+               bmp->Palette = (UCHAR*) calloc( BMP_PALETTE_SIZE, sizeof( UCHAR 
) );
+               if ( bmp->Palette == NULL )
+               {
+                       BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
+                       free( bmp );
+                       return NULL;
+               }
+       }
+       else
+       {
+               bmp->Palette = NULL;
+       }
+
+
+       /* Allocate pixels */
+       bmp->Data = (UCHAR*) calloc( bmp->Header.ImageDataSize, sizeof( UCHAR ) 
);
+       if ( bmp->Data == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
+               free( bmp->Palette );
+               free( bmp );
+               return NULL;
+       }
+
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+
+       return bmp;
+}
+
+
+/**************************************************************
+       Frees all the memory used by the specified BMP image.
+**************************************************************/
+void BMP_Free( BMP* bmp )
+{
+       if ( bmp == NULL )
+       {
+               return;
+       }
+
+       if ( bmp->Palette != NULL )
+       {
+               free( bmp->Palette );
+       }
+
+       if ( bmp->Data != NULL )
+       {
+               free( bmp->Data );
+       }
+
+       free( bmp );
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+}
+
+
+/**************************************************************
+       Reads the specified BMP image file.
+**************************************************************/
+BMP* BMP_ReadFile( const char* filename )
+{
+       BMP*    bmp;
+       FILE*   f;
+
+       if ( filename == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+               return NULL;
+       }
+
+
+       /* Allocate */
+       bmp = calloc( 1, sizeof( BMP ) );
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+
+       /* Open file */
+       f = fopen( filename, "rb" );
+       if ( f == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND;
+               free( bmp );
+               return NULL;
+       }
+
+
+       /* Read header */
+       if ( ReadHeader( bmp, f ) != BMP_OK || bmp->Header.Magic != 0x4D42 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
+               fclose( f );
+               free( bmp );
+               return NULL;
+       }
+
+
+       /* Verify that the bitmap variant is supported */
+       if ( ( bmp->Header.BitsPerPixel != 32 && bmp->Header.BitsPerPixel != 24 
&& bmp->Header.BitsPerPixel != 8 )
+               || bmp->Header.CompressionType != 0 || bmp->Header.HeaderSize 
!= 40 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED;
+               fclose( f );
+               free( bmp );
+               return NULL;
+       }
+
+
+       /* Allocate and read palette */
+       if ( bmp->Header.BitsPerPixel == 8 )
+       {
+               bmp->Palette = (UCHAR*) malloc( BMP_PALETTE_SIZE * sizeof( 
UCHAR ) );
+               if ( bmp->Palette == NULL )
+               {
+                       BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
+                       fclose( f );
+                       free( bmp );
+                       return NULL;
+               }
+
+               if ( fread( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f 
) != BMP_PALETTE_SIZE )
+               {
+                       BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
+                       fclose( f );
+                       free( bmp->Palette );
+                       free( bmp );
+                       return NULL;
+               }
+       }
+       else    /* Not an indexed image */
+       {
+               bmp->Palette = NULL;
+       }
+
+
+       /* Allocate memory for image data */
+       bmp->Data = (UCHAR*) malloc( bmp->Header.ImageDataSize );
+       if ( bmp->Data == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
+               fclose( f );
+               free( bmp->Palette );
+               free( bmp );
+               return NULL;
+       }
+
+
+       /* Read image data */
+       if ( fread( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) 
!= bmp->Header.ImageDataSize )
+       {
+               BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
+               fclose( f );
+               free( bmp->Data );
+               free( bmp->Palette );
+               free( bmp );
+               return NULL;
+       }
+
+
+       fclose( f );
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+
+       return bmp;
+}
+
+
+/**************************************************************
+       Writes the BMP image to the specified file.
+**************************************************************/
+void BMP_WriteFile( BMP* bmp, const char* filename )
+{
+       FILE*   f;
+
+       if ( filename == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+               return;
+       }
+
+
+       /* Open file */
+       f = fopen( filename, "wb" );
+       if ( f == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND;
+               return;
+       }
+
+
+       /* Write header */
+       if ( WriteHeader( bmp, f ) != BMP_OK )
+       {
+               BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
+               fclose( f );
+               return;
+       }
+
+
+       /* Write palette */
+       if ( bmp->Palette )
+       {
+               if ( fwrite( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f 
) != BMP_PALETTE_SIZE )
+               {
+                       BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
+                       fclose( f );
+                       return;
+               }
+       }
+
+
+       /* Write data */
+       if ( fwrite( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) 
!= bmp->Header.ImageDataSize )
+       {
+               BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
+               fclose( f );
+               return;
+       }
+
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+       fclose( f );
+}
+
+
+/**************************************************************
+       Returns the image's width.
+**************************************************************/
+UINT BMP_GetWidth( BMP* bmp )
+{
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+               return -1;
+       }
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+
+       return ( bmp->Header.Width );
+}
+
+
+/**************************************************************
+       Returns the image's height.
+**************************************************************/
+UINT BMP_GetHeight( BMP* bmp )
+{
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+               return -1;
+       }
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+
+       return ( bmp->Header.Height );
+}
+
+
+/**************************************************************
+       Returns the image's color depth (bits per pixel).
+**************************************************************/
+USHORT BMP_GetDepth( BMP* bmp )
+{
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+               return -1;
+       }
+
+       BMP_LAST_ERROR_CODE = BMP_OK;
+
+       return ( bmp->Header.BitsPerPixel );
+}
+
+
+/**************************************************************
+       Populates the arguments with the specified pixel's RGB
+       values.
+**************************************************************/
+void BMP_GetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b )
+{
+       UCHAR*  pixel;
+       UINT    bytes_per_row;
+       UCHAR   bytes_per_pixel;
+
+       if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= 
bmp->Header.Height )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+       }
+       else
+       {
+               BMP_LAST_ERROR_CODE = BMP_OK;
+
+               bytes_per_pixel = bmp->Header.BitsPerPixel >> 3;
+
+               /* Row's size is rounded up to the next multiple of 4 bytes */
+               bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
+
+               /* Calculate the location of the relevant pixel (rows are 
flipped) */
+               pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * 
bytes_per_row + x * bytes_per_pixel );
+
+
+               /* In indexed color mode the pixel's value is an index within 
the palette */
+               if ( bmp->Header.BitsPerPixel == 8 )
+               {
+                       pixel = bmp->Palette + *pixel * 4;
+               }
+
+               /* Note: colors are stored in BGR order */
+               if ( r )        *r = *( pixel + 2 );
+               if ( g )        *g = *( pixel + 1 );
+               if ( b )        *b = *( pixel + 0 );
+       }
+}
+
+
+/**************************************************************
+       Sets the specified pixel's RGB values.
+**************************************************************/
+void BMP_SetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b )
+{
+       UCHAR*  pixel;
+       UINT    bytes_per_row;
+       UCHAR   bytes_per_pixel;
+
+       if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= 
bmp->Header.Height )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+       }
+
+       else if ( bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 
32 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
+       }
+
+       else
+       {
+               BMP_LAST_ERROR_CODE = BMP_OK;
+
+               bytes_per_pixel = bmp->Header.BitsPerPixel >> 3;
+
+               /* Row's size is rounded up to the next multiple of 4 bytes */
+               bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
+
+               /* Calculate the location of the relevant pixel (rows are 
flipped) */
+               pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * 
bytes_per_row + x * bytes_per_pixel );
+
+               /* Note: colors are stored in BGR order */
+               *( pixel + 2 ) = r;
+               *( pixel + 1 ) = g;
+               *( pixel + 0 ) = b;
+       }
+}
+
+
+/**************************************************************
+       Gets the specified pixel's color index.
+**************************************************************/
+void BMP_GetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR* val )
+{
+       UCHAR*  pixel;
+       UINT    bytes_per_row;
+
+       if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= 
bmp->Header.Height )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+       }
+
+       else if ( bmp->Header.BitsPerPixel != 8 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
+       }
+
+       else
+       {
+               BMP_LAST_ERROR_CODE = BMP_OK;
+
+               /* Row's size is rounded up to the next multiple of 4 bytes */
+               bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
+
+               /* Calculate the location of the relevant pixel */
+               pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * 
bytes_per_row + x );
+
+
+               if ( val )      *val = *pixel;
+       }
+}
+
+
+/**************************************************************
+       Sets the specified pixel's color index.
+**************************************************************/
+void BMP_SetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR val )
+{
+       UCHAR*  pixel;
+       UINT    bytes_per_row;
+
+       if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= 
bmp->Header.Height )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+       }
+
+       else if ( bmp->Header.BitsPerPixel != 8 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
+       }
+
+       else
+       {
+               BMP_LAST_ERROR_CODE = BMP_OK;
+
+               /* Row's size is rounded up to the next multiple of 4 bytes */
+               bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
+
+               /* Calculate the location of the relevant pixel */
+               pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * 
bytes_per_row + x );
+
+               *pixel = val;
+       }
+}
+
+
+/**************************************************************
+       Gets the color value for the specified palette index.
+**************************************************************/
+void BMP_GetPaletteColor( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b )
+{
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+       }
+
+       else if ( bmp->Header.BitsPerPixel != 8 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
+       }
+
+       else
+       {
+               if ( r )        *r = *( bmp->Palette + index * 4 + 2 );
+               if ( g )        *g = *( bmp->Palette + index * 4 + 1 );
+               if ( b )        *b = *( bmp->Palette + index * 4 + 0 );
+
+               BMP_LAST_ERROR_CODE = BMP_OK;
+       }
+}
+
+
+/**************************************************************
+       Sets the color value for the specified palette index.
+**************************************************************/
+void BMP_SetPaletteColor( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b )
+{
+       if ( bmp == NULL )
+       {
+               BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
+       }
+
+       else if ( bmp->Header.BitsPerPixel != 8 )
+       {
+               BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
+       }
+
+       else
+       {
+               *( bmp->Palette + index * 4 + 2 ) = r;
+               *( bmp->Palette + index * 4 + 1 ) = g;
+               *( bmp->Palette + index * 4 + 0 ) = b;
+
+               BMP_LAST_ERROR_CODE = BMP_OK;
+       }
+}
+
+
+/**************************************************************
+       Returns the last error code.
+**************************************************************/
+BMP_STATUS BMP_GetError()
+{
+       return BMP_LAST_ERROR_CODE;
+}
+
+
+/**************************************************************
+       Returns a description of the last error code.
+**************************************************************/
+const char* BMP_GetErrorDescription()
+{
+       if ( BMP_LAST_ERROR_CODE > 0 && BMP_LAST_ERROR_CODE < BMP_ERROR_NUM )
+       {
+               return BMP_ERROR_STRING[ BMP_LAST_ERROR_CODE ];
+       }
+       else
+       {
+               return NULL;
+       }
+}
+
+
+
+
+
+/*********************************** Private methods 
**********************************/
+
+
+/**************************************************************
+       Reads the BMP file's header into the data structure.
+       Returns BMP_OK on success.
+**************************************************************/
+int    ReadHeader( BMP* bmp, FILE* f )
+{
+       if ( bmp == NULL || f == NULL )
+       {
+               return BMP_INVALID_ARGUMENT;
+       }
+
+       /* The header's fields are read one by one, and converted from the 
format's
+       little endian to the system's native representation. */
+       if ( !ReadUSHORT( &( bmp->Header.Magic ), f ) )                 return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.FileSize ), f ) )                return 
BMP_IO_ERROR;
+       if ( !ReadUSHORT( &( bmp->Header.Reserved1 ), f ) )             return 
BMP_IO_ERROR;
+       if ( !ReadUSHORT( &( bmp->Header.Reserved2 ), f ) )             return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.DataOffset ), f ) )              return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.HeaderSize ), f ) )              return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.Width ), f ) )                   return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.Height ), f ) )                  return 
BMP_IO_ERROR;
+       if ( !ReadUSHORT( &( bmp->Header.Planes ), f ) )                return 
BMP_IO_ERROR;
+       if ( !ReadUSHORT( &( bmp->Header.BitsPerPixel ), f ) )  return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.CompressionType ), f ) ) return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.ImageDataSize ), f ) )   return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.HPixelsPerMeter ), f ) ) return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.VPixelsPerMeter ), f ) ) return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.ColorsUsed ), f ) )              return 
BMP_IO_ERROR;
+       if ( !ReadUINT( &( bmp->Header.ColorsRequired ), f ) )  return 
BMP_IO_ERROR;
+
+       return BMP_OK;
+}
+
+
+/**************************************************************
+       Writes the BMP file's header into the data structure.
+       Returns BMP_OK on success.
+**************************************************************/
+int    WriteHeader( BMP* bmp, FILE* f )
+{
+       if ( bmp == NULL || f == NULL )
+       {
+               return BMP_INVALID_ARGUMENT;
+       }
+
+       /* The header's fields are written one by one, and converted to the 
format's
+       little endian representation. */
+       if ( !WriteUSHORT( bmp->Header.Magic, f ) )                     return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.FileSize, f ) )            return 
BMP_IO_ERROR;
+       if ( !WriteUSHORT( bmp->Header.Reserved1, f ) )         return 
BMP_IO_ERROR;
+       if ( !WriteUSHORT( bmp->Header.Reserved2, f ) )         return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.DataOffset, f ) )          return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.HeaderSize, f ) )          return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.Width, f ) )                       return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.Height, f ) )                      return 
BMP_IO_ERROR;
+       if ( !WriteUSHORT( bmp->Header.Planes, f ) )            return 
BMP_IO_ERROR;
+       if ( !WriteUSHORT( bmp->Header.BitsPerPixel, f ) )      return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.CompressionType, f ) )     return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.ImageDataSize, f ) )       return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.HPixelsPerMeter, f ) )     return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.VPixelsPerMeter, f ) )     return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.ColorsUsed, f ) )          return 
BMP_IO_ERROR;
+       if ( !WriteUINT( bmp->Header.ColorsRequired, f ) )      return 
BMP_IO_ERROR;
+
+       return BMP_OK;
+}
+
+
+/**************************************************************
+       Reads a little-endian unsigned int from the file.
+       Returns non-zero on success.
+**************************************************************/
+int    ReadUINT( UINT* x, FILE* f )
+{
+       UCHAR little[ 4 ];      /* BMPs use 32 bit ints */
+
+       if ( x == NULL || f == NULL )
+       {
+               return 0;
+       }
+
+       if ( fread( little, 4, 1, f ) != 1 )
+       {
+               return 0;
+       }
+
+       *x = ( little[ 3 ] << 24 | little[ 2 ] << 16 | little[ 1 ] << 8 | 
little[ 0 ] );
+
+       return 1;
+}
+
+
+/**************************************************************
+       Reads a little-endian unsigned short int from the file.
+       Returns non-zero on success.
+**************************************************************/
+int    ReadUSHORT( USHORT *x, FILE* f )
+{
+       UCHAR little[ 2 ];      /* BMPs use 16 bit shorts */
+
+       if ( x == NULL || f == NULL )
+       {
+               return 0;
+       }
+
+       if ( fread( little, 2, 1, f ) != 1 )
+       {
+               return 0;
+       }
+
+       *x = ( little[ 1 ] << 8 | little[ 0 ] );
+
+       return 1;
+}
+
+
+/**************************************************************
+       Writes a little-endian unsigned int to the file.
+       Returns non-zero on success.
+**************************************************************/
+int    WriteUINT( UINT x, FILE* f )
+{
+       UCHAR little[ 4 ];      /* BMPs use 32 bit ints */
+
+       little[ 3 ] = (UCHAR)( ( x & 0xff000000 ) >> 24 );
+       little[ 2 ] = (UCHAR)( ( x & 0x00ff0000 ) >> 16 );
+       little[ 1 ] = (UCHAR)( ( x & 0x0000ff00 ) >> 8 );
+       little[ 0 ] = (UCHAR)( ( x & 0x000000ff ) >> 0 );
+
+       return ( f && fwrite( little, 4, 1, f ) == 1 );
+}
+
+
+/**************************************************************
+       Writes a little-endian unsigned short int to the file.
+       Returns non-zero on success.
+**************************************************************/
+int    WriteUSHORT( USHORT x, FILE* f )
+{
+       UCHAR little[ 2 ];      /* BMPs use 16 bit shorts */
+
+       little[ 1 ] = (UCHAR)( ( x & 0xff00 ) >> 8 );
+       little[ 0 ] = (UCHAR)( ( x & 0x00ff ) >> 0 );
+
+       return ( f && fwrite( little, 2, 1, f ) == 1 );
+}
+
diff --git a/glyphtest/qdbmp.h b/glyphtest/qdbmp.h
new file mode 100755
index 0000000..d6c0e6c
--- /dev/null
+++ b/glyphtest/qdbmp.h
@@ -0,0 +1,133 @@
+#ifndef _BMP_H_
+#define _BMP_H_
+
+
+/**************************************************************
+
+       QDBMP - Quick n' Dirty BMP
+
+       v1.0.0 - 2007-04-07
+       http://qdbmp.sourceforge.net
+
+
+       The library supports the following BMP variants:
+       1. Uncompressed 32 BPP (alpha values are ignored)
+       2. Uncompressed 24 BPP
+       3. Uncompressed 8 BPP (indexed color)
+
+       QDBMP is free and open source software, distributed
+       under the MIT licence.
+
+       Copyright (c) 2007 Chai Braudo (address@hidden)
+
+       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 <stdio.h>
+
+
+
+/* Type definitions */
+#ifndef UINT
+       #define UINT    unsigned long int
+#endif
+
+#ifndef USHORT
+       #define USHORT  unsigned short
+#endif
+
+#ifndef UCHAR
+       #define UCHAR   unsigned char
+#endif
+
+
+/* Version */
+#define QDBMP_VERSION_MAJOR            1
+#define QDBMP_VERSION_MINOR            0
+#define QDBMP_VERSION_PATCH            1
+
+
+/* Error codes */
+typedef enum
+{
+       BMP_OK = 0,                             /* No error */
+       BMP_ERROR,                              /* General error */
+       BMP_OUT_OF_MEMORY,              /* Could not allocate enough memory to 
complete the operation */
+       BMP_IO_ERROR,                   /* General input/output error */
+       BMP_FILE_NOT_FOUND,             /* File not found */
+       BMP_FILE_NOT_SUPPORTED, /* File is not a supported BMP variant */
+       BMP_FILE_INVALID,               /* File is not a BMP image or is an 
invalid BMP */
+       BMP_INVALID_ARGUMENT,   /* An argument is invalid or out of range */
+       BMP_TYPE_MISMATCH,              /* The requested action is not 
compatible with the BMP's type */
+       BMP_ERROR_NUM
+} BMP_STATUS;
+
+
+/* Bitmap image */
+typedef struct _BMP BMP;
+
+
+
+
+/*********************************** Public methods 
**********************************/
+
+
+/* Construction/destruction */
+BMP*                   BMP_Create                                      ( UINT 
width, UINT height, USHORT depth );
+void                   BMP_Free                                        ( BMP* 
bmp );
+
+
+/* I/O */
+BMP*                   BMP_ReadFile                            ( const char* 
filename );
+void                   BMP_WriteFile                           ( BMP* bmp, 
const char* filename );
+
+
+/* Meta info */
+UINT                   BMP_GetWidth                            ( BMP* bmp );
+UINT                   BMP_GetHeight                           ( BMP* bmp );
+USHORT                 BMP_GetDepth                            ( BMP* bmp );
+
+
+/* Pixel access */
+void                   BMP_GetPixelRGB                         ( BMP* bmp, 
UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b );
+void                   BMP_SetPixelRGB                         ( BMP* bmp, 
UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b );
+void                   BMP_GetPixelIndex                       ( BMP* bmp, 
UINT x, UINT y, UCHAR* val );
+void                   BMP_SetPixelIndex                       ( BMP* bmp, 
UINT x, UINT y, UCHAR val );
+
+
+/* Palette handling */
+void                   BMP_GetPaletteColor                     ( BMP* bmp, 
UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b );
+void                   BMP_SetPaletteColor                     ( BMP* bmp, 
UCHAR index, UCHAR r, UCHAR g, UCHAR b );
+
+
+/* Error handling */
+BMP_STATUS             BMP_GetError                            ();
+const char*            BMP_GetErrorDescription         ();
+
+
+/* Useful macro that may be used after each BMP operation to check for an 
error */
+#define BMP_CHECK_ERROR( output_file, return_value ) \
+       if ( BMP_GetError() != BMP_OK )                                         
                                                        \
+       {                                                                       
                                                                                
        \
+               fprintf( ( output_file ), "BMP error: %s\n", 
BMP_GetErrorDescription() );       \
+               return( return_value );                                         
                                                                \
+       }                                                                       
                                                                                
        \
+
+#endif



reply via email to

[Prev in Thread] Current Thread [Next in Thread]