You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.0 KiB
112 lines
3.0 KiB
/* Copyright 2014-2017 Alex 'AdUser' Z (ad_user@runbox.com) |
|
* |
|
* This file is part of libsimdb |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License version 2 as |
|
* published by the Free Software Foundation. |
|
*/ |
|
|
|
#include "../common.h" |
|
#include "../bitmap.h" |
|
#include "../record.h" |
|
#include "../simdb.h" |
|
|
|
#include <wand/magick_wand.h> |
|
|
|
simdb_urec_t * |
|
simdb_record_create(const char * const path) { |
|
MagickWand *wand = NULL; |
|
MagickPassFail status = MagickPass; |
|
uint16_t w = 0, h = 0; |
|
size_t buf_size = 64 * sizeof(char); |
|
unsigned char *buf = NULL; |
|
simdb_urec_t *rec = NULL; |
|
|
|
assert(path != NULL); |
|
|
|
InitializeMagick("/"); |
|
wand = NewMagickWand(); |
|
if (status == MagickPass) |
|
status = MagickReadImage(wand, path); |
|
|
|
if (status == MagickPass) |
|
w = MagickGetImageWidth(wand); |
|
|
|
if (status == MagickPass) |
|
h = MagickGetImageHeight(wand); |
|
|
|
/* 2 -> 160 : width, "cols" */ |
|
/* 3 -> 160 : width, "rows" */ |
|
if (status == MagickPass) |
|
status = MagickSampleImage(wand, 160, 160); |
|
|
|
/** TODO: color maps */ |
|
|
|
/* 2 -> 256 : number of colors */ |
|
/* 4 -> 0 : treedepth -> auto */ |
|
/* 5 -> 0 : dither -> none */ |
|
/* 6 -> 0 : measure_error -> none */ |
|
if (status == MagickPass) |
|
status = MagickQuantizeImage(wand, 256, GRAYColorspace, 0, 0, 0); |
|
|
|
/* 2 -> 3 : radius, in pixels */ |
|
/* 3 -> 2 : "for reasonable results, radius should be larger than sigma" */ |
|
if (status == MagickPass) |
|
status = MagickBlurImage(wand, 3, 2); |
|
|
|
if (status == MagickPass) |
|
status = MagickNormalizeImage(wand); |
|
|
|
if (status == MagickPass) |
|
status = MagickEqualizeImage(wand); |
|
|
|
/* 2 -> 16 : width, "cols" */ |
|
/* 3 -> 16 : width, "rows" */ |
|
if (status == MagickPass) |
|
status = MagickSampleImage(wand, 16, 16); |
|
|
|
/* 2 -> 50%, tuned by magick number, see 'magick/image.h' */ |
|
if (status == MagickPass) |
|
status = MagickThresholdImage(wand, 50.0 * (MaxRGB / 100)); |
|
|
|
if (status == MagickPass) |
|
status = MagickSetImageType(wand, BilevelType); |
|
|
|
if (status == MagickPass) |
|
status = MagickSetImageFormat(wand, "MONO"); |
|
|
|
if (status == MagickPass) |
|
buf = MagickWriteImageBlob(wand, &buf_size); |
|
|
|
#ifdef DEBUG |
|
if (status == MagickPass) { |
|
fprintf(stderr, "sample H: %lu\n", MagickGetImageWidth(wand)); |
|
fprintf(stderr, "sample W: %lu\n", MagickGetImageWidth(wand)); |
|
fprintf(stderr, "buf size: %zu\n", buf_size); |
|
for (unsigned int i = 0; i < buf_size; i++) |
|
fprintf(stderr, "%02X", buf[i]); |
|
} |
|
#endif |
|
|
|
if (status == MagickPass) { |
|
assert(buf_size == SIMDB_BITMAP_SIZE); |
|
if ((rec = calloc(1, sizeof(simdb_urec_t))) != NULL) { |
|
rec->used = 0xFF; |
|
rec->image_w = w; |
|
rec->image_h = h; |
|
memcpy(rec->bitmap, buf, SIMDB_BITMAP_SIZE); |
|
} |
|
#ifdef DEBUG |
|
} else { |
|
ExceptionType severity = 0; |
|
char *description = MagickGetException(wand, &severity); |
|
fprintf(stderr, "%03d %.1024s\n", severity, description); |
|
#endif |
|
} |
|
|
|
DestroyMagickWand(wand); |
|
DestroyMagick(); |
|
|
|
return rec; |
|
}
|
|
|