#include "common.h" #include "bitmap.h" #include "database.h" #include "sample.h" #include int imdb_sample(imdb_rec_t * const rec, const char * const source) { MagickWand *wand = NULL; MagickPassFail status = MagickPass; ExceptionType severity = 0; uint16_t w = 0, h = 0; char *description = NULL; size_t buf_size = 64 * sizeof(char); unsigned char *buf = NULL; InitializeMagick("/"); /* FIXME */ wand = NewMagickWand(); if (status == MagickPass) status = MagickReadImage(wand, source); 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 == 32); memset(rec->data, 0x0, IMDB_REC_LEN); rec->data[REC_OFF_RU] = 0xFF; memcpy(&rec->data[REC_OFF_IW], &w, sizeof(uint16_t)); memcpy(&rec->data[REC_OFF_IH], &h, sizeof(uint16_t)); memcpy(&rec->data[REC_OFF_BM], buf, BITMAP_SIZE); } else { description = MagickGetException(wand, &severity); fprintf(stderr, "%03d %.1024s\n", severity, description); } DestroyMagickWand(wand); DestroyMagick(); return (status == MagickPass) ? 0 : -1; }