diff --git a/tests/web_interface/bitmap.c b/tests/web_interface/bitmap.c new file mode 100644 index 000000000..5d7e3c36a --- /dev/null +++ b/tests/web_interface/bitmap.c @@ -0,0 +1,269 @@ +#include "bitmap.h" + +HASH_128 * Generate_Hash_x64_128(FT_Bitmap * bitmap, HASH_128 * murmur) +{ + int seed = 99; // Dont change + + MurmurHash3_x64_128(bitmap->buffer, (bitmap->pitch * bitmap->rows), seed, murmur->hash); + + return murmur; +} + +HASH_128 * Generate_Hash_x86_128(FT_Bitmap * bitmap, HASH_128 * murmur) +{ + int seed = 99; // Dont change + + MurmurHash3_x86_128(bitmap->buffer, (bitmap->pitch * bitmap->rows), seed, murmur->hash); + + return murmur; +} + +HASH_32 * Generate_Hash_x86_32(FT_Bitmap * bitmap, HASH_32 * murmur) +{ + int seed = 99; // Dont change + + MurmurHash3_x86_32(bitmap->buffer, (bitmap->pitch * bitmap->rows), seed, murmur->hash); + + return murmur; +} + +int Get_Padding( FT_Bitmap* bitmap ){ + + int rem; + if (bitmap->pixel_mode == 6) + { + rem = ( 3 * bitmap->width ) % 4; + }else{ + rem = ( bitmap->width ) % 4; + } + + if (!rem ) + { + return rem; + } + return (4 - rem); +} + +int Get_Bits_Per_Pixel ( unsigned char PIXEL_MODE) { + if (PIXEL_MODE < 5) + { + return BITS_PER_PIXEL_GRAY; + }else{ + return BITS_PER_PIXEL_LCD; + } +} + +void Write_Bitmap_Header (FT_Bitmap * bitmap, char * fname ) { + + FILE *fp = fopen(fname,"w"); // Bitmap File + HEADER *header = ( HEADER* ) calloc( 1 , sizeof( HEADER )); + + unsigned char pixel_mode = ( bitmap->pixel_mode ); + FT_UInt image_width; + FT_UInt image_rows; + FT_UInt color_table_size = 0; + + switch(pixel_mode){ + + case 5 : image_width = bitmap->width / 3; // LCD + image_rows = bitmap->rows; + break; + + case 6 : image_width = bitmap->width; // LCD_V + image_rows = bitmap->rows / 3; + break; + + default : image_width = bitmap->width; // MONO and GRAY + image_rows = bitmap->rows; + color_table_size = 4* 256; + break; + } + + FT_Int image_size; + image_size = (image_rows * image_width ); + + header->file_header.type = 0x4D42; + header->file_header.file_size = sizeof(HEADER) + color_table_size + image_size; + header->file_header.file_offset = sizeof(HEADER) + color_table_size; + + header->info_header.info_header_size = sizeof(BMP_INFO_HEADER); + header->info_header.width = image_width ; + header->info_header.height = - image_rows; + header->info_header.planes = PLANES; + header->info_header.bits_per_pixel = Get_Bits_Per_Pixel( bitmap->pixel_mode ); + header->info_header.compression = COMPRESSION; + header->info_header.image_size = image_size; + header->info_header.y_pixels_per_meter = Y_PIXELS_PER_METER ; + header->info_header.x_pixels_per_meter = X_PIXELS_PER_METER ; + header->info_header.used_colors = USED_COLORS; + header->info_header.important_colors = IMPORTANT_COLORS; + + fwrite (header, 1, sizeof(HEADER),fp); + free(header); + fclose(fp); +} + +void Write_Bitmap_Data_LCD_RGB( FT_Bitmap * bitmap, char * fname ){ + + char value; + int i,j,k; + + FILE *fp = fopen(fname,"a"); + + for (i = 0; i < bitmap->rows ; ++i) + { + for ( j = 2; j < bitmap->width; j = j+3) + { + for ( k = 0; k < 3; ++k) + { + value = 0xff - bitmap->buffer[( i * bitmap->pitch) + j - k]; + fwrite (&value, 1, 1,fp); + } + } + for ( k = 0; k < Get_Padding(bitmap); ++k) + { + value = 0xff; + fwrite (&value, 1, 1,fp); + } + } + + fclose(fp); +} + +void Write_Bitmap_Data_LCD_BGR( FT_Bitmap * bitmap, char * fname ){ + + char value; + int i,j,k; + + FILE *fp = fopen(fname,"a"); + + for ( i = 0; i < bitmap->rows ; ++i) + { + for ( j = 0; j < bitmap->width; j++) + { + value = 0xff - bitmap->buffer[( i * bitmap->pitch) + j]; + fwrite (&value, 1, 1,fp); + } + for ( k = 0; k < Get_Padding(bitmap); ++k) + { + value = 0xff; + fwrite (&value, 1, 1,fp); + } + } + + fclose(fp); +} + +void Write_Bitmap_Data_LCD_V_BGR (FT_Bitmap * bitmap, char * fname) { + + FILE *fp = fopen(fname,"a"); + + int i,j,k,step; + char value; + step = 0; + + while ( step < bitmap->rows ){ + + for (i = 0; i < bitmap->width; i++) + { + for (j = step ; j < step + 3; ++j) + { + value = 0xff - bitmap->buffer[(j * bitmap->pitch) + i]; + fwrite (&value, 1, 1,fp); + } + } + for (k = 0; k < Get_Padding(bitmap); ++k) + { + value = 0xff; + fwrite (&value, 1, 1,fp); + } + step = step + 3; // Jumping 3 rows up + } + + fclose(fp); +} + +void Write_Bitmap_Data_LCD_V_RGB (FT_Bitmap * bitmap, char * fname) { + + FILE *fp = fopen(fname,"a"); + + int i,j,k,step; + char value; + step = 0; + + while ( step < bitmap->rows ){ + + for (i = 0; i < bitmap->width; i++) + { + for (j = step + 2 ; j >= step; --j) + { + value = 0xff - bitmap->buffer[(j * bitmap->pitch) + i]; + fwrite (&value, 1, 1,fp); + } + } + for (k = 0; k < Get_Padding(bitmap); ++k) + { + value = 0xff; + fwrite (&value, 1, 1,fp); + } + step = step + 3; // Jumping 3 rows up + } + + fclose(fp); +} + +void Write_Bitmap_Data_MONO (FT_Bitmap * bitmap, char * fname) { + + FILE *fp = fopen(fname,"a"); + + int i; + unsigned char value; + for ( i = 0; i < 256; ++i) + { + value = i; + fwrite (&value,1,1,fp); + fwrite (&value,1,1,fp); + fwrite (&value,1,1,fp); + value = 0; + fwrite (&value,1,1,fp); + } + + + for (int i = 0; i < bitmap->pitch * bitmap->rows; ++i) + { + if ( bitmap->buffer[i] != 0x00 ){ + value = 0x00; // remember taking reverse + fwrite (&value, 1, 1,fp); + }else{ + value = 0xff; + fwrite (&value, 1, 1,fp); + } + } + + fclose(fp); +} + +void Write_Bitmap_Data_GRAY(FT_Bitmap * bitmap, char * fname) { + + FILE *fp = fopen(fname,"a"); + int i; + + unsigned char value; + for ( i = 0; i < 256; ++i) + { + value = i; + fwrite (&value,1,1,fp); + fwrite (&value,1,1,fp); + fwrite (&value,1,1,fp); + value = 0; + fwrite (&value,1,1,fp); + } + + for (int i = 0; i < bitmap->pitch * bitmap->rows; ++i) + { + value = 255 - bitmap->buffer[i]; + fwrite(&value,1,1,fp); + } + + fclose(fp); +} \ No newline at end of file diff --git a/tests/web_interface/bitmap.h b/tests/web_interface/bitmap.h new file mode 100644 index 000000000..e8945de47 --- /dev/null +++ b/tests/web_interface/bitmap.h @@ -0,0 +1,86 @@ +#include +#include +#include +#include "murmur3.h" // MurmurHash3_x64_128 header file + +#include FT_FREETYPE_H +#include FT_MODULE_H +#include FT_LCD_FILTER_H +#include FT_BITMAP_H + +#define BITS_PER_PIXEL_MONO 1 // Constants for the Bitmap Header +#define BITS_PER_PIXEL_GRAY 8 +#define BITS_PER_PIXEL_LCD 24 + +#define PLANES 1 // Constants for the Bitmap Header +#define COMPRESSION 0 +#define X_PIXELS_PER_METER 0 +#define Y_PIXELS_PER_METER 0 +#define USED_COLORS 0 +#define IMPORTANT_COLORS 0 +//------------------------------------------------------------------------------- +#pragma pack(push,1) + +typedef struct{ // Bitmap FILE Header + + FT_UInt16 type; + FT_UInt32 file_size; + FT_UInt32 reserved; + FT_UInt32 file_offset; + +} BMP_FILE_HEADER; + +typedef struct{ // Bitmap INFO Header + + FT_UInt32 info_header_size; + FT_UInt32 width; + FT_Int height; + FT_UInt16 planes; + FT_UInt16 bits_per_pixel; + FT_UInt32 compression; + FT_UInt32 image_size; + FT_UInt32 y_pixels_per_meter; + FT_UInt32 x_pixels_per_meter; + FT_UInt32 used_colors; + FT_UInt32 important_colors; + +} BMP_INFO_HEADER; + +typedef struct { // Bitmap Header + + BMP_FILE_HEADER file_header; + BMP_INFO_HEADER info_header; + +} HEADER; + +//------------------------------------------------------------------------------ +typedef struct { // To store 32bit Hash + FT_UInt32 hash[1]; +}HASH_32; + +typedef struct { // To store 128bit Hash + FT_UInt32 hash[4]; +}HASH_128; + +#pragma pack(pop) + +//------------------------------------------------------------------------------- + +HASH_32 * Generate_Hash_x86_32(FT_Bitmap * bitmap, HASH_32 * murmur); +HASH_128 * Generate_Hash_x86_128(FT_Bitmap * bitmap, HASH_128 * murmur); +HASH_128 * Generate_Hash_x64_128(FT_Bitmap * bitmap, HASH_128 * murmur); + +//------------------------------------------------------------------------------- + +int Get_Padding (FT_Bitmap * bitmap); + +int Get_Bits_Per_Pixel ( unsigned char PIXEL_MODE ); + +void Write_Bitmap_Header (FT_Bitmap * bitmap, char * fname); + +void Write_Bitmap_Data_MONO (FT_Bitmap * bitmap, char * fname); +void Write_Bitmap_Data_GRAY (FT_Bitmap * bitmap, char * fname); +void Write_Bitmap_Data_LCD_BGR (FT_Bitmap * bitmap, char * fname); +void Write_Bitmap_Data_LCD_RGB (FT_Bitmap * bitmap, char * fname); +void Write_Bitmap_Data_LCD_V_RGB (FT_Bitmap * bitmap, char * fname); +void Write_Bitmap_Data_LCD_V_BGR (FT_Bitmap * bitmap, char * fname); diff --git a/tests/web_interface/compare-new-to-old.c b/tests/web_interface/compare-new-to-old.c new file mode 100644 index 000000000..52942a7f4 --- /dev/null +++ b/tests/web_interface/compare-new-to-old.c @@ -0,0 +1,103 @@ +#include "bitmap.h" + +int main(int argc, char const * argv[]) +{ + FT_Library library; + FT_Face face; + FT_GlyphSlot slot; + FT_Bitmap * bitmap; + FT_UInt32 size; + + const char * filename; + + int i, j; + + char mmhash[40]; + unsigned int lines; + int line_len = 40; + char ** hashes; + char fname[20]; + + FILE * fp = fopen("old-hashes.txt", "r"); + + filename = argv[1]; + size = atoi(argv[2]); + + if (FT_Init_FreeType(&library)) + { + printf("Error: library init.\n"); + } + + if (FT_New_Face(library, filename, 0, &face)) + { + printf("Error: loading face.\n"); + } + + lines = face->num_glyphs; + hashes = (char **)malloc(sizeof(char*)*lines); + + for (i = 0; i < lines; i++) + { + hashes[i] = malloc(line_len); + if (hashes[i]==NULL) + { + fprintf(stderr,"Out of memory (3).\n"); + exit(4); + } + if (fgets(hashes[i],line_len-1,fp)==NULL) + break; + + /* Get rid of CR or LF at end of line */ + for (j=strlen(hashes[i])-1;j>=0 && (hashes[i][j]=='\n' || hashes[i][j]=='\r');j--) + ; + hashes[i][j+1]='\0'; + } + fclose(fp); + + if (FT_Set_Char_Size(face, size * 64, 0, 96, 0)) + { + printf("Error: setting char size.\n"); + } + + slot = face->glyph; + + for (i = 0; i < face->num_glyphs; ++i) + { + if (FT_Load_Glyph(face, i, FT_LOAD_DEFAULT)) + { + printf("Error: loading glyph.\n"); + } + + if (FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL)) + { + printf("Error: rendering glyph.\n"); + } + + bitmap = &slot->bitmap; + + HASH_128 * murmur = (HASH_128 *)malloc(sizeof(HASH_128)); + murmur = Generate_Hash_x64_128(bitmap,murmur); + + sprintf(mmhash, "%08x%08x%08x%08x", murmur->hash[0], murmur->hash[1], murmur->hash[2], murmur->hash[3]); + + printf("%s\n", hashes[i]); + printf("%s\n", mmhash); + if (strcmp(mmhash, hashes[i]) == 0) + { + if (bitmap->width != 0 && bitmap->rows !=0) + { + printf("Glyph %d differs.\n", i); + sprintf(fname, "%d-new.bmp", i); + Write_Bitmap_Header(bitmap, fname); + Write_Bitmap_Data_GRAY(bitmap, fname); + } + } + + } + + FT_Done_Face(face); + FT_Done_FreeType(library); + + return 0; + +} \ No newline at end of file diff --git a/tests/web_interface/generate-old-hashes.c b/tests/web_interface/generate-old-hashes.c new file mode 100644 index 000000000..13b6304af --- /dev/null +++ b/tests/web_interface/generate-old-hashes.c @@ -0,0 +1,64 @@ +#include "bitmap.h" + +int main(int argc, char const * argv[]) +{ + FT_Library library; + FT_Face face; + FT_GlyphSlot slot; + FT_Bitmap * bitmap; + FT_UInt32 size; + + const char * filename; + + int i; + + FILE * fp = fopen("old-hashes.txt", "w"); + + filename = argv[1]; + size = atoi(argv[2]); + + if (FT_Init_FreeType(&library)) + { + printf("Error: library init.\n"); + } + + if (FT_New_Face(library, filename, 0, &face)) + { + printf("Error: loading face.\n"); + } + + if (FT_Set_Char_Size(face, size * 64, 0, 96, 0)) + { + printf("Error: setting char size.\n"); + } + + slot = face->glyph; + + for (i = 0; i < face->num_glyphs; ++i) + { + if (FT_Load_Glyph(face, i, FT_LOAD_DEFAULT)) + { + printf("Error: loading glyph.\n"); + } + + if (FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL)) + { + printf("Error: rendering glyph.\n"); + } + + bitmap = &slot->bitmap; + + HASH_128 * murmur = (HASH_128 *)malloc(sizeof(HASH_128)); + murmur = Generate_Hash_x64_128(bitmap, murmur); + + fprintf(fp, "%08x%08x%08x%08x\n", murmur->hash[0], murmur->hash[1], murmur->hash[2], murmur->hash[3]); + } + + fclose(fp); + + FT_Done_Face(face); + FT_Done_FreeType(library); + + return 0; + +} \ No newline at end of file diff --git a/tests/web_interface/main-2.c b/tests/web_interface/main-2.c deleted file mode 100644 index eb042bf88..000000000 --- a/tests/web_interface/main-2.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#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, 255 - byte, 255 - byte, 255 - 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/tests/web_interface/main.c b/tests/web_interface/main.c deleted file mode 100644 index 45adda66f..000000000 --- a/tests/web_interface/main.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#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, 255 - byte, 255 - byte, 255 - 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/tests/web_interface/murmur3.c b/tests/web_interface/murmur3.c new file mode 100644 index 000000000..484ebfd03 --- /dev/null +++ b/tests/web_interface/murmur3.c @@ -0,0 +1,312 @@ +//----------------------------------------------------------------------------- +// Note - The x86 and x64 versions do _not_ produce the same results, as the +// algorithms are optimized for their respective platforms. You can still +// compile and run any of them on any platform, but your performance with the +// non-native version will be less than optimal. + +#include "murmur3.h" + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +#ifdef __GNUC__ +#define FORCE_INLINE __attribute__((always_inline)) inline +#else +#define FORCE_INLINE inline +#endif + +static FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r ) +{ + return (x << r) | (x >> (32 - r)); +} + +static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r ) +{ + return (x << r) | (x >> (64 - r)); +} + +#define ROTL32(x,y) rotl32(x,y) +#define ROTL64(x,y) rotl64(x,y) + +#define BIG_CONSTANT(x) (x##LLU) + +//----------------------------------------------------------------------------- +// Block read - if your platform needs to do endian-swapping or can only +// handle aligned reads, do the conversion here + +#define getblock(p, i) (p[i]) + +//----------------------------------------------------------------------------- +// Finalization mix - force all bits of a hash block to avalanche + +static FORCE_INLINE uint32_t fmix32 ( uint32_t h ) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +//---------- + +static FORCE_INLINE uint64_t fmix64 ( uint64_t k ) +{ + k ^= k >> 33; + k *= BIG_CONSTANT(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return k; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32 ( const void * key, int len, + uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 4; + int i; + + uint32_t h1 = seed; + + uint32_t c1 = 0xcc9e2d51; + uint32_t c2 = 0x1b873593; + + //---------- + // body + + const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); + + for(i = -nblocks; i; i++) + { + uint32_t k1 = getblock(blocks,i); + + k1 *= c1; + k1 = ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1,13); + h1 = h1*5+0xe6546b64; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*4); + + uint32_t k1 = 0; + + switch(len & 3) + { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; + + h1 = fmix32(h1); + + *(uint32_t*)out = h1; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_128 ( const void * key, const int len, + uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 16; + int i; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + uint32_t c1 = 0x239b961b; + uint32_t c2 = 0xab0e9789; + uint32_t c3 = 0x38b34ae5; + uint32_t c4 = 0xa1e38b93; + + //---------- + // body + + const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); + + for(i = -nblocks; i; i++) + { + uint32_t k1 = getblock(blocks,i*4+0); + uint32_t k2 = getblock(blocks,i*4+1); + uint32_t k3 = getblock(blocks,i*4+2); + uint32_t k4 = getblock(blocks,i*4+3); + + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + + h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; + + k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; + + h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; + + k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; + + h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; + + k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; + + h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch(len & 15) + { + case 15: k4 ^= tail[14] << 16; + case 14: k4 ^= tail[13] << 8; + case 13: k4 ^= tail[12] << 0; + k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; + + case 12: k3 ^= tail[11] << 24; + case 11: k3 ^= tail[10] << 16; + case 10: k3 ^= tail[ 9] << 8; + case 9: k3 ^= tail[ 8] << 0; + k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; + + case 8: k2 ^= tail[ 7] << 24; + case 7: k2 ^= tail[ 6] << 16; + case 6: k2 ^= tail[ 5] << 8; + case 5: k2 ^= tail[ 4] << 0; + k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; + + case 4: k1 ^= tail[ 3] << 24; + case 3: k1 ^= tail[ 2] << 16; + case 2: k1 ^= tail[ 1] << 8; + case 1: k1 ^= tail[ 0] << 0; + k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + h1 = fmix32(h1); + h2 = fmix32(h2); + h3 = fmix32(h3); + h4 = fmix32(h4); + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + ((uint32_t*)out)[0] = h1; + ((uint32_t*)out)[1] = h2; + ((uint32_t*)out)[2] = h3; + ((uint32_t*)out)[3] = h4; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x64_128 ( const void * key, const int len, + const uint32_t seed, void * out ) +{ + const uint8_t * data = (const uint8_t*)key; + const int nblocks = len / 16; + int i; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); + uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); + + //---------- + // body + + const uint64_t * blocks = (const uint64_t *)(data); + + for(i = 0; i < nblocks; i++) + { + uint64_t k1 = getblock(blocks,i*2+0); + uint64_t k2 = getblock(blocks,i*2+1); + + k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; + + h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; + + k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; + + h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch(len & 15) + { + case 15: k2 ^= (uint64_t)(tail[14]) << 48; + case 14: k2 ^= (uint64_t)(tail[13]) << 40; + case 13: k2 ^= (uint64_t)(tail[12]) << 32; + case 12: k2 ^= (uint64_t)(tail[11]) << 24; + case 11: k2 ^= (uint64_t)(tail[10]) << 16; + case 10: k2 ^= (uint64_t)(tail[ 9]) << 8; + case 9: k2 ^= (uint64_t)(tail[ 8]) << 0; + k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; + + case 8: k1 ^= (uint64_t)(tail[ 7]) << 56; + case 7: k1 ^= (uint64_t)(tail[ 6]) << 48; + case 6: k1 ^= (uint64_t)(tail[ 5]) << 40; + case 5: k1 ^= (uint64_t)(tail[ 4]) << 32; + case 4: k1 ^= (uint64_t)(tail[ 3]) << 24; + case 3: k1 ^= (uint64_t)(tail[ 2]) << 16; + case 2: k1 ^= (uint64_t)(tail[ 1]) << 8; + case 1: k1 ^= (uint64_t)(tail[ 0]) << 0; + k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + + ((uint64_t*)out)[0] = h1; + ((uint64_t*)out)[1] = h2; +} + +//----------------------------------------------------------------------------- + diff --git a/tests/web_interface/murmur3.h b/tests/web_interface/murmur3.h new file mode 100644 index 000000000..90878b00d --- /dev/null +++ b/tests/web_interface/murmur3.h @@ -0,0 +1,24 @@ +#ifndef _MURMURHASH3_H_ +#define _MURMURHASH3_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out); + +void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out); + +void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out); + +//----------------------------------------------------------------------------- + +#ifdef __cplusplus +} +#endif + +#endif // _MURMURHASH3_H_ diff --git a/tests/web_interface/qdbmp.c b/tests/web_interface/qdbmp.c deleted file mode 100755 index fd1337277..000000000 --- a/tests/web_interface/qdbmp.c +++ /dev/null @@ -1,798 +0,0 @@ -#include "qdbmp.h" -#include -#include - - -/* 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/tests/web_interface/qdbmp.h b/tests/web_interface/qdbmp.h deleted file mode 100755 index d6c0e6c45..000000000 --- a/tests/web_interface/qdbmp.h +++ /dev/null @@ -1,133 +0,0 @@ -#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 (braudo@users.sourceforge.net) - - 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 - - - -/* 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