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;
}
示例#2
0
文件: zbarimg.c 项目: AquaGeek/zbar
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);
}
示例#3
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 {