struct bufferAndSize pngQuant(MagickWand *output){ unsigned long wid = MagickGetImageWidth(output); unsigned long hei = MagickGetImageHeight(output); unsigned char *bmp_buffer; bmp_buffer = (unsigned char*) malloc(wid*hei*4); MagickGetImagePixels(output,0,0,wid,hei,"RGBA",CharPixel,bmp_buffer); liq_attr *attr = liq_attr_create(); liq_image *qimage = liq_image_create_rgba(attr, bmp_buffer, wid, hei, 0); liq_set_max_colors(attr, 255); liq_set_speed(attr, 10); liq_result *res = liq_quantize_image(attr, qimage); int png_buffer_size = wid*hei; unsigned char *png_buffer = malloc(png_buffer_size); liq_write_remapped_image(res, qimage, png_buffer, png_buffer_size); const liq_palette *pal = liq_get_palette(res); LodePNGState state; lodepng_state_init(&state); /*optionally customize the state*/ state.info_png.color.bitdepth = 8; state.info_png.color.colortype = LCT_PALETTE; state.info_raw.colortype = LCT_PALETTE; state.info_raw.bitdepth = 8; state.encoder.auto_convert = 0; state.encoder.add_id = 0; state.encoder.zlibsettings.nicematch = 258; int i = 0; for (i=0; i < pal->count; ++i) { lodepng_palette_add(&state.info_png.color, pal->entries[i].r , pal->entries[i].g, pal->entries[i].b, pal->entries[i].a); lodepng_palette_add(&state.info_raw, pal->entries[i].r , pal->entries[i].g, pal->entries[i].b, pal->entries[i].a); } unsigned char *data; size_t size = 0; lodepng_encode(&data, &size, png_buffer, wid, hei, &state); // writtendata = io_write(size, data); lodepng_state_cleanup(&state); free(bmp_buffer); free(png_buffer); liq_attr_destroy(attr); liq_image_destroy(qimage); liq_result_destroy(res); lodepng_state_cleanup(&state); struct bufferAndSize bs; bs.data = data; bs.size = size; return bs; }
static int scan_image (const char *filename) { if(exit_code == 3) return(-1); int found = 0; MagickWand *images = NewMagickWand(); if(!MagickReadImage(images, filename) && dump_error(images)) return(-1); unsigned seq, n = MagickGetNumberImages(images); for(seq = 0; seq < n; seq++) { if(exit_code == 3) return(-1); if(!MagickSetImageIndex(images, seq) && dump_error(images)) return(-1); zbar_image_t *zimage = zbar_image_create(); assert(zimage); zbar_image_set_format(zimage, zbar_fourcc('Y','8','0','0')); int width = MagickGetImageWidth(images); int height = MagickGetImageHeight(images); zbar_image_set_size(zimage, width, height); // extract grayscale image pixels // FIXME color!! ...preserve most color w/422P // (but only if it's a color image) size_t bloblen = width * height; unsigned char *blob = malloc(bloblen); zbar_image_set_data(zimage, blob, bloblen, zbar_image_free_data); if(!MagickGetImagePixels(images, 0, 0, width, height, "I", CharPixel, blob)) return(-1); if(xmllvl == 1) { xmllvl++; printf("<source href='%s'>\n", filename); } zbar_process_image(processor, zimage); // output result data const zbar_symbol_t *sym = zbar_image_first_symbol(zimage); for(; sym; sym = zbar_symbol_next(sym)) { zbar_symbol_type_t typ = zbar_symbol_get_type(sym); unsigned len = zbar_symbol_get_data_length(sym); if(typ == ZBAR_PARTIAL) continue; else if(xmllvl <= 0) { if(!xmllvl) printf("%s:", zbar_get_symbol_name(typ)); if(len && fwrite(zbar_symbol_get_data(sym), len, 1, stdout) != 1) { exit_code = 1; return(-1); } } else { if(xmllvl < 3) { xmllvl++; printf("<index num='%u'>\n", seq); } zbar_symbol_xml(sym, &xmlbuf, &xmlbuflen); if(fwrite(xmlbuf, xmlbuflen, 1, stdout) != 1) { exit_code = 1; return(-1); } } printf("\n"); found++; num_symbols++; } if(xmllvl > 2) { xmllvl--; printf("</index>\n"); } fflush(stdout); zbar_image_destroy(zimage); num_images++; if(zbar_processor_is_visible(processor)) { int rc = zbar_processor_user_wait(processor, -1); if(rc < 0 || rc == 'q' || rc == 'Q') exit_code = 3; } } if(xmllvl > 1) { xmllvl--; printf("</source>\n"); } if(!found) notfound++; DestroyMagickWand(images); return(0); }
// Open Image ptImage* ptImage::ptGMCOpenImage(const char* FileName, short ColorSpace, short Intent, short ScaleFactor, bool IsRAW, TImage8RawData* ImgData, bool& Success) { Success = 0; MagickWand* image = NewMagickWand(); ExceptionType MagickExcept; if (IsRAW) { MagickReadImageBlob(image, (const uchar*)ImgData->data(), (const size_t)ImgData->size()); } else { if (!QFile::exists(QString::fromLocal8Bit(FileName))) return this; MagickReadImage(image, FileName); } MagickGetException(image, &MagickExcept); if (MagickExcept != UndefinedException) { return this; } Success = 1; // Get the embedded profile cmsHPROFILE InProfile = NULL; if (MagickGetImageType(image) != GrayscaleType) { ulong ProfileLength = 0; uchar* IccProfile = MagickGetImageProfile(image, "ICC", &ProfileLength); if (ProfileLength > 0) { InProfile = cmsOpenProfileFromMem(IccProfile, ProfileLength); } } if (!InProfile) { InProfile = cmsCreate_sRGBProfile(); } MagickSetImageType(image, TrueColorType); MagickSetImageFormat(image, "RGB"); MagickSetImageDepth(image, 16); uint16_t NewWidth = MagickGetImageWidth(image); uint16_t NewHeight = MagickGetImageHeight(image); // Buffer for the data from Magick std::vector<std::array<float, 3> > ImageBuffer; ImageBuffer.resize((size_t) NewWidth*NewHeight); MagickGetImagePixels(image, 0, 0, NewWidth, NewHeight, "RGB", FloatPixel, (uchar*)ImageBuffer.data()); m_Width = NewWidth; DestroyMagickWand(image); // Image before color transform, may be binned std::vector<std::array<float, 3> > NewImage; if (ScaleFactor != 0) { // Binning NewHeight >>= ScaleFactor; NewWidth >>= ScaleFactor; short Step = 1 << ScaleFactor; int Average = pow(2,2 * ScaleFactor); NewImage.resize((size_t)NewWidth*NewHeight); #pragma omp parallel for schedule(static) for (uint16_t Row=0; Row < NewHeight*Step; Row+=Step) { for (uint16_t Col=0; Col < NewWidth*Step; Col+=Step) { float PixelValue[3] = {0.0f,0.0f,0.0f}; for (uint8_t sRow=0; sRow < Step; sRow++) { for (uint8_t sCol=0; sCol < Step; sCol++) { int32_t index = (Row+sRow)*m_Width+Col+sCol; for (short c=0; c < 3; c++) { PixelValue[c] += ImageBuffer[index][c]; } } } for (short c=0; c < 3; c++) { NewImage[Row/Step*NewWidth+Col/Step][c] = PixelValue[c] / Average; } } } } else {