Skip to content

Instantly share code, notes, and snippets.

@vmxdev
Created November 19, 2016 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vmxdev/3f81581eea9add508d79c1f8fd16de5c to your computer and use it in GitHub Desktop.
Save vmxdev/3f81581eea9add508d79c1f8fd16de5c to your computer and use it in GitHub Desktop.
t1ha hash function map
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
#include <stdint.h>
#include "t1ha.h"
#define STRLEN 10
#define NITER 1000000
/*#define SQRSIDE 842*/
#define SQRSIDE 800
/* A coloured pixel. */
typedef struct {
uint8_t red;
uint8_t green;
uint8_t blue;
} pixel_t;
/* A picture. */
typedef struct {
pixel_t *pixels;
size_t width;
size_t height;
} bitmap_t;
static pixel_t *
pixel_at (bitmap_t * bitmap, int x, int y)
{
return bitmap->pixels + bitmap->width * y + x;
}
static int
save_png_to_file(bitmap_t *bitmap, const char *path)
{
FILE * fp;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
size_t x, y;
png_byte ** row_pointers = NULL;
/* "status" contains the return value of this function. At first
it is set to a value which means 'failure'. When the routine
has finished its work, it is set to a value which means
'success'. */
int status = -1;
/* The following number is set by trial and error only. I cannot
see where it it is documented in the libpng manual.
*/
int pixel_size = 3;
int depth = 8;
fp = fopen (path, "wb");
if (!fp) {
goto fopen_failed;
}
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
goto png_create_write_struct_failed;
}
info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) {
goto png_create_info_struct_failed;
}
/* Set up error handling. */
if (setjmp(png_jmpbuf(png_ptr))) {
goto png_failure;
}
/* Set image attributes. */
png_set_IHDR(png_ptr,
info_ptr,
bitmap->width,
bitmap->height,
depth,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
/* Initialize rows of PNG. */
row_pointers = png_malloc(png_ptr, bitmap->height * sizeof(png_byte *));
for (y=0; y<bitmap->height; y++) {
png_byte *row =
png_malloc (png_ptr,
sizeof (uint8_t) * bitmap->width * pixel_size);
row_pointers[y] = row;
for (x=0; x<bitmap->width; x++) {
pixel_t * pixel = pixel_at(bitmap, x, y);
*row++ = pixel->red;
*row++ = pixel->green;
*row++ = pixel->blue;
}
}
/* Write the image data to "fp". */
png_init_io(png_ptr, fp);
png_set_rows(png_ptr, info_ptr, row_pointers);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
/* The routine has successfully written the file, so we set
"status" to a value which indicates success. */
status = 0;
for (y=0; y<bitmap->height; y++) {
png_free(png_ptr, row_pointers[y]);
}
png_free(png_ptr, row_pointers);
png_failure:
png_create_info_struct_failed:
png_destroy_write_struct(&png_ptr, &info_ptr);
png_create_write_struct_failed:
fclose (fp);
fopen_failed:
return status;
}
static void
mkstr(char *data)
{
int i;
for (i=0; i<STRLEN-1; i++) {
data[i] = rand() % 10 + '0';
}
data[STRLEN-1] = '\0';
}
int
main()
{
char data[STRLEN];
int i;
uint64_t h;
uint64_t *map, maxc;
bitmap_t img;
uint32_t x, y;
map = calloc(sizeof(uint64_t), SQRSIDE * SQRSIDE);
maxc = 0;
img.width = SQRSIDE;
img.height = SQRSIDE;
img.pixels = calloc(img.width * img.height, sizeof(pixel_t));
for (i=0; i<NITER; i++) {
mkstr(data);
h = t1ha(data, STRLEN, 1);
/*printf("%s: %lu\n", data, h);*/
x = (uint32_t)h;
y = h >> 32;
x = (uint64_t)x * SQRSIDE / UINT32_MAX;
y = (uint64_t)y * SQRSIDE / UINT32_MAX;
map[x + y * SQRSIDE]++;
maxc = maxc < map[x + y * SQRSIDE] ? map[x + y * SQRSIDE] : maxc;
}
for (x=0; x<SQRSIDE; x++) {
for (y=0; y<SQRSIDE; y++) {
pixel_t *p = pixel_at(&img, x, y);
if (map[x + y * SQRSIDE]) {
p->red = p->green = p->blue = 0;
} else {
p->red = p->green = p->blue = 200;
}
}
}
save_png_to_file(&img, "hashmap.png");
free(img.pixels);
free(map);
printf("maxc: %lu\n", maxc);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment