Exemplo n.º 1
0
caddr_t 
bif_im_CreateImageBlob (caddr_t * qst, caddr_t * err, state_slot_t ** args)
{
  im_env_t env;
  char * szMe = "IM CreateImageBlob";
  caddr_t res;
  long x_size = bif_long_arg (qst, args, 0, szMe);
  long y_size = bif_long_arg (qst, args, 1, szMe);
  caddr_t bg_color = (caddr_t)bif_string_arg (qst, args, 2, szMe);
  caddr_t fmt = (caddr_t)bif_string_arg (qst, args, 3, szMe);
  im_init (&env, qst, args, "IM CreateImageBlob");
  if (x_size <= 0 || y_size <= 0)
    im_leave_with_error (&env, "22023", "IM001", "Negative image size");
  if (x_size*y_size > 3333279) /* 10M / 3 color - 54byte */
    im_leave_with_error (&env, "22023", "IM001", "Too large image image size requested");
  im_set_background (&env, bg_color);
  env.ime_status = MagickNewImage (env.ime_magick_wand, x_size, y_size, env.ime_background);
  if (env.ime_status == MagickFalse)
    im_leave_with_error (&env, "22023", "IM001", "Cannot create image");
  env.ime_status = MagickSetImageFormat (env.ime_magick_wand, fmt);
  if (env.ime_status == MagickFalse)
    im_leave_with_error (&env, "22023", "IM001", "Cannot set image format");
  res = im_write (&env);
  im_leave (&env);
  return res;
}
Exemplo n.º 2
0
int main(int argc,char **argv) {
    MagickWand *magick_wand;
    MagickBooleanType status;

    MagickWandGenesis();
    magick_wand = NewMagickWand();

    MagickSetResourceLimit(MemoryResource, 1000 * 1000);
    MagickSetResourceLimit(DiskResource, 1000 * 1000);
    

    status = MagickReadImage(magick_wand, "./images/picture-100M-6000x6000.png");

    if (status == MagickFalse) {
        printf("Failed to MagickReadImage");
        return -1;
    }

    printf("This shouldn't be reached - the image is larger than the area resource.\n");

    MagickSetImageFormat(magick_wand, "png");

    status = MagickWriteImages(magick_wand, "./output/resource_output.png", MagickTrue);
    if (status == MagickFalse) {
        printf("Failed to MagickWriteImages");
        return -1;
    }

    MagickWandTerminus();
 
    return(0);
}
Exemplo n.º 3
0
static zbar_image_t *_php_zbarcode_get_page(MagickWand *wand) 
{
	unsigned long width, height;
	unsigned char *image_data;
	size_t image_size;
	
	if (MagickSetImageDepth(wand, 8) == MagickFalse) {
		return NULL;
	}

	if (MagickSetImageFormat(wand, "GRAY") == MagickFalse) {
		return NULL;
	}
	
	width  = MagickGetImageWidth(wand);
	height = MagickGetImageHeight(wand);

	image_data = malloc(width * height);
	
	if (!MagickExportImagePixels(wand, 0, 0, width, height, "I", CharPixel, image_data)) {
		return NULL;
	}
	
	return _php_zbarcode_image_create(width, height, image_data);
}
Exemplo n.º 4
0
caddr_t bif_im_ConvertImageBlob (caddr_t * qst, caddr_t * err, state_slot_t ** args)
{
  im_env_t env;
  caddr_t res;
        char out_name[64];
  caddr_t format = bif_string_arg (qst, args, 2, "IM ConvertImageBlob");
  im_init (&env, qst, args, "IM ConvertImageBlob");
  im_env_set_input_blob (&env, 0);
  im_env_set_blob_ext (&env, 3, -1);
  im_read (&env);

        if (env.ime_input_ext != NULL)
        {
                if (strlen(format) < 30)
                {
                        strcpy(out_name, "image.");                                                                                                                                                               
                        strcat(out_name, format);                                                                                                                                                              
                }
	}
  MagickResetIterator (env.ime_magick_wand);
  while (MagickNextImage (env.ime_magick_wand) != MagickFalse)
  {
    env.ime_status = MagickSetImageFormat (env.ime_magick_wand, format);
    MagickSetFilename (env.ime_magick_wand, out_name);
    if (env.ime_status == MagickFalse)
      im_leave_with_error (&env, "22023", "IM001", "bif_im_ConvertImageBlob cannot convert image");
    }
  res = im_write (&env);
  im_leave (&env);
  return res;
}
Exemplo n.º 5
0
caddr_t bif_im_DeepZoom4to1 (caddr_t * qst, caddr_t * err, state_slot_t ** args)
  {
  im_env_t env;
  caddr_t res;
  int fmt_is_set = 0;
  int image_ctr;
  im_init (&env, qst, args, "IM DeepZoom4to1");
  im_set_background (&env, "#000000");
  env.ime_target_magick_wand = NewMagickWand ();
  if (MagickFalse == MagickNewImage (env.ime_target_magick_wand, 256, 256, env.ime_background))
    im_leave_with_error (&env, "22023", "IM001", "Can not make new image");
  if (MagickFalse == MagickSetImageType (env.ime_target_magick_wand, TrueColorType))
    im_leave_with_error (&env, "22023", "IM001", "Can not set image type");
  if (MagickFalse == MagickSetImageDepth (env.ime_target_magick_wand, 16))
    im_leave_with_error (&env, "22023", "IM001", "Can not set image depth");
  if (MagickFalse == MagickSetImageExtent (env.ime_target_magick_wand, 256, 256))
    im_leave_with_error (&env, "22023", "IM001", "Can not set image extent");
  if (MagickFalse == MagickSetImageBackgroundColor (env.ime_target_magick_wand, env.ime_background))
    im_leave_with_error (&env, "22023", "IM001", "Can not set image background");
  image_ctr = BOX_ELEMENTS (args) / 2;
  if (image_ctr > 4)
    image_ctr = 4;
  while (0 < image_ctr--)
    {
      if (DV_DB_NULL == DV_TYPE_OF (bif_arg (qst, args, image_ctr*2, "IM DeepZoom4to1")))
        continue;
      im_env_set_input_blob (&env, image_ctr * 2);
      /*im_env_set_blob_ext (&env, 2);*/
      im_read (&env);
      MagickResetIterator (env.ime_magick_wand);
      while (MagickNextImage (env.ime_magick_wand) != MagickFalse)
        {
          unsigned long v_size, h_size;
          if (!fmt_is_set)
            {
              if (MagickFalse == MagickSetImageFormat (env.ime_target_magick_wand, MagickGetImageFormat (env.ime_magick_wand)))
                im_leave_with_error (&env, "22023", "IM001", "Can not set image format");
              fmt_is_set = 1;
            }
          h_size = MagickGetImageWidth (env.ime_magick_wand);
          v_size = MagickGetImageHeight (env.ime_magick_wand);
          if ((256 < h_size) || (256 < v_size))
            continue;
          MagickResizeImage (env.ime_magick_wand, h_size/2, v_size/2, BoxFilter, 1.0);
          if (MagickFalse == MagickCompositeImage (env.ime_target_magick_wand, env.ime_magick_wand, OverCompositeOp, (image_ctr & 1) * 128, (image_ctr & 2) * 64))
            im_leave_with_error (&env, "22023", "IM001", "Can not composite image");
        }
      im_reset_read (&env);
    }
  MagickProfileImage (env.ime_target_magick_wand, "*", NULL, 0);
  DestroyMagickWand (env.ime_magick_wand);
  env.ime_magick_wand = env.ime_target_magick_wand;
  env.ime_target_magick_wand = NULL;
  res = im_write (&env);
  im_leave (&env);
  return res;
}
Exemplo n.º 6
0
static int set_wi_format(lua_State *L) {
    const char *format = lua_tostring(L, 1);
    
    lua_arg *larg = pthread_getspecific(thread_key);
    int ret = MagickSetImageFormat(larg->img, format);
    LOG_PRINT(LOG_DEBUG, "set_wi_format: %s ret = %d", format, ret);
    lua_pushnumber(L, ret);
    return 1;
}
Exemplo n.º 7
0
Object c_Gmagick::t_setimageformat(CStrRef format) {
  INSTANCE_METHOD_INJECTION_BUILTIN(Gmagick, Gmagick::setimageformat);
  checkNotEmpty();
  
  int result = MagickSetImageFormat(magick_wand, format->data());
  checkResult(result);

  return this;
}
Exemplo n.º 8
0
Arquivo: zimg.c Projeto: Codefor/zimg
char* get_phone_img(const char *phone_str, size_t *img_size){
    if(phone_str == NULL){
	return NULL;
    }

    MagickWand *m_wand  = NULL;
    PixelWand *p_wand  = NULL;
    DrawingWand *d_wand = NULL;


    /* Create a wand */
    m_wand = NewMagickWand();
    p_wand = NewPixelWand();
    d_wand = NewDrawingWand();

    PixelSetColor(p_wand,"white");

    int height = 18;
    int width = strlen(phone_str) * 130 / 12;

    MagickNewImage(m_wand, width,height ,p_wand);

    //draw number
    PixelSetColor(p_wand,"black");
    DrawSetFillColor(d_wand,p_wand);
    DrawSetFont (d_wand, "Arial" ) ;
    DrawSetFontSize(d_wand,20);
    DrawSetStrokeColor(d_wand,p_wand);
    DrawAnnotation(d_wand,0,height -2,phone_str);
    MagickDrawImage(m_wand,d_wand);
    //MagickTrimImage(m_wand,0);
    //ImageFormat MUST be SET,otherwise,otherwise we will not MagickGetImageBlob properly
    MagickSetImageFormat(m_wand,"JPEG");

    char *p = NULL;
    char *data = NULL;

    p = (char *)MagickGetImageBlob(m_wand,img_size);

    if(p != NULL){
	data = (char *)malloc(*img_size);
	if(data != NULL){
	    memcpy(data,p,*img_size);
	}else{
	    LOG_PRINT(LOG_INFO, "malloc Failed!");
	}
    }else{
	LOG_PRINT(LOG_INFO, "MagickGetImageBlob Failed!");
    }
    
    /* Tidy up */
    MagickRelinquishMemory(p);
    DestroyMagickWand(m_wand);
    DestroyPixelWand(p_wand);

    return data;
}
Exemplo n.º 9
0
bool ImageMagickGIFEncoderOpen(struct ImageMagickGIFEncoder* encoder, const char* outfile) {
	MagickWandGenesis();
	encoder->wand = NewMagickWand();
	MagickSetImageFormat(encoder->wand, "GIF");
	MagickSetImageDispose(encoder->wand, PreviousDispose);
	encoder->outfile = strdup(outfile);
	encoder->frame = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4);
	encoder->currentFrame = 0;
	return true;
}
Exemplo n.º 10
0
void save_image(ConvertContext *context) {
    int result = RESULT_OK;
    char *error_desc;
    ExceptionType error_type;
	
    // get pixel data
    if (context->hasAlphaChannel == MagickTrue) {
        if (MagickImportImagePixels(context->mw, 0, 0, context->imageWidth, context->imageHeight, "ARGB", CharPixel, context->pixels)  == MagickFalse) {
            error_desc = MagickGetException(context->mw, &error_type);
            asprintf(&context->results.message, "Error exporting pixel data (%s): %s\n",error_desc,context->src_path);
            error_desc = (char *)MagickRelinquishMemory(error_desc);
            result += RESULT_ERROR;
        }
    }
    
    // convert image to PNG
    if (result == RESULT_OK) {
        if (MagickSetImageFormat(context->mw,"PNG") == MagickFalse) {
            error_desc = MagickGetException(context->mw, &error_type);
			asprintf(&context->results.message,"Error converting image (%s): %s\n",error_desc,context->src_path);
            error_desc = (char *)MagickRelinquishMemory(error_desc);
            result += RESULT_ERROR;
        }
    }
	
	// activate/deactivate alpha channel
	MagickSetImageAlphaChannel(context->mw, (context->results.alpha_type == ALPHA_TYPE_NONE ? DeactivateAlphaChannel : ActivateAlphaChannel));

    // make sure image is saved as RGB and not crunched down to grayscale
	MagickSetType(context->mw, (context->results.alpha_type == ALPHA_TYPE_NONE ? TrueColorType : TrueColorMatteType));
	
	// save image to disk
    if (result == RESULT_OK) {
        if (MagickWriteImage(context->mw, context->dst_path) == MagickFalse) {
            error_desc = MagickGetException(context->mw, &error_type);
            asprintf(&context->results.message, "Error saving image (%s): %s\n",error_desc,context->dst_path);
            error_desc = (char *)MagickRelinquishMemory(error_desc);
            result += RESULT_ERROR;
        }
    }
	
	if (result == RESULT_OK && context->options.delete_original != 0) {
		if (unlink(context->src_path) == -1) {
			asprintf(&context->results.message, "Unable to delete original image (%s): %s\n", strerror(errno), context->src_path);
			result += RESULT_ERROR;
		}
    }
    
	// cleanup and report results
	context->results.result = result;
	dispatch_group_async_f(context->conv_group, dispatch_get_main_queue(), context, (void (*)(void *))finish_image);
}
Exemplo n.º 11
0
    unsigned char* process(EIM_FORMAT fmt, size_t *new_length)
    {
        //long unsigned int number_properties;
        //char **properties = MagickGetImageProperties(magick_wand, "*", &number_properties);
        ////void *MagickRelinquishMemory(void *resource)
        //std::cout << "Profiles: " << std::endl;
        //if (properties != (char **) NULL)
        //{
        //    for (ssize_t i=0; i < (ssize_t)number_properties; i++)
        //    {
        //        char *property = MagickGetImageProperty(magick_wand,properties[i]);
        //        std::cout << properties[i] << std::endl;
        //        std::cout << property << std::endl;
        //        properties[i]=(char *) MagickRelinquishMemory(properties[i]);
        //    }
        //    properties=(char **) MagickRelinquishMemory(properties);
        //}
        
        //orientation is stored in the data we're about to strip, so correct the image first
        reorientate();
        MagickStripImage(magick_wand);
        
        status = MagickSetImageFormat(magick_wand, "jpg");
        // MagickWand * old_img = magick_wand;
        magick_wand = MagickMergeImageLayers(magick_wand, FlattenLayer);
        // MagickDestroyImage(old_img);
/*        switch(fmt)
        {
            case EIM_FORMAT_JPG:
                status=MagickSetImageFormat(magick_wand, "jpg");
                break;
            case EIM_FORMAT_GIF:
                status=MagickSetImageFormat(magick_wand, "gif");
                break;
            case EIM_FORMAT_PNG:
            default:
                status=MagickSetImageFormat(magick_wand, "png");
                break;
        }*/
        if (status == MagickFalse) {
            throw("An error occured");
        }
        unsigned char *new_blob;
        new_blob = MagickGetImageBlob(magick_wand,new_length);

        magick_wand=DestroyMagickWand(magick_wand);
        MagickWandTerminus();
        return new_blob;
    }
Exemplo n.º 12
0
//==============================================================================
// We don't want to use the saving function of QImage, since this requires the
// format plugins to be shipped.
bool ptImageHelper::DumpImage(QImage* AImage, const QString AFileName) {
  long unsigned int Width  = AImage->width();
  long unsigned int Height = AImage->height();

  MagickWand *mw;
  mw = NewMagickWand();
  MagickSetSize(mw, Width, Height);
  MagickReadImage(mw,"xc:white");
  MagickSetImageFormat(mw,"BGRA");
  MagickSetImageDepth(mw,8);
  MagickSetImageType(mw,TrueColorType);

  MagickSetImagePixels(mw,0,0,Width,Height,"BGRA",CharPixel,(unsigned char*) AImage->bits());

  MagickSetImageDepth(mw,8);

  MagickSetImageFormat(mw,"RGB");
  MagickSetCompressionQuality(mw,95);
  MagickSetImageCompression(mw, LZWCompression);

  bool Result = MagickWriteImage(mw, AFileName.toLocal8Bit().data());
  DestroyMagickWand(mw);
  return Result;
}
Exemplo n.º 13
0
unsigned char *iac_image_get_blob(MagickWand *wand, size_t *data_size)
{
    unsigned char *blob;

    /* Set image format of blob */
    if (MagickSetImageFormat(wand, IAC_IMAGE_BLOB_FORMAT) == MagickFalse) {
        iac_image_exception(wand);
        return NULL;
    }

    /* Get image blob from wand */
    blob = MagickGetImageBlob(wand, data_size);
    if (blob == NULL) {
        iac_image_exception(wand);
        return NULL;
    }

    return blob;
}
// build a B&W circle GIF in memory and return a pointer to it.
static void* ngx_http_circle_gif_template(int req_radius, size_t* image_length_ptr, 
	MagickWand *wand, PixelWand *bg_wand, PixelWand *fg_wand, DrawingWand *dwand)
{
  float radius = req_radius - 0.5;

  ClearDrawingWand(dwand);
  PixelSetColor(bg_wand, "#000000");
  PixelSetColor(fg_wand, "#ffffff");
  MagickNewImage(wand, req_radius*2, req_radius*2, bg_wand);
  DrawSetFillColor(dwand, fg_wand);
  DrawCircle(dwand, radius, radius, 0, radius);
  MagickDrawImage(wand, dwand);
  MagickSetImageFormat(wand, "gif");

  unsigned char *image = MagickGetImageBlob(wand, image_length_ptr);

  MagickRemoveImage(wand);
  return image;
}
Exemplo n.º 15
0
static PyObject *
im_SetImageFormat(PyObject *self, PyObject *args) {

	void *magick_pointer;
	MagickWand *magick_wand;
	char *format = NULL;
	MagickBooleanType status;

	if (!PyArg_ParseTuple(args, "Os", &magick_pointer, &format)){
		return Py_BuildValue("i", 0);
	}

	magick_wand = (MagickWand *) PyCObject_AsVoidPtr(magick_pointer);
	status = MagickSetImageFormat(magick_wand, format);

	if (status == MagickFalse){
		return Py_BuildValue("i", 0);
	}

	return Py_BuildValue("i", 1);
}
Exemplo n.º 16
0
Object c_Gmagick::t_newimage(int64 columns, int64 rows, CStrRef background, CStrRef format) {
  INSTANCE_METHOD_INJECTION_BUILTIN(Gmagick, Gmagick::newimage);
  char xc_str[MAX_BUFFER_SIZE];

  if (background.empty()) {
    throwException("The color must not be empty", ImageError);
  }

  snprintf((char *)&xc_str, MAX_BUFFER_SIZE, "xc:%s", background.data());
  int result = MagickReadImage(magick_wand, xc_str);
  checkResult(result);

  result = MagickScaleImage(magick_wand, columns, rows);
  checkResult(result);
  
  if (format.size() > 0) {
    result = MagickSetImageFormat(magick_wand, format.data());
    checkResult(result);
  }

  return this;
}
Exemplo n.º 17
0
// just write an image to disk for testing
bool ptImage::DumpImage(const char* FileName) const {

  long unsigned int Width  = m_Width;
  long unsigned int Height = m_Height;

  MagickWand *mw;
  mw = NewMagickWand();
  MagickSetSize(mw, Width, Height);
  MagickReadImage(mw,"xc:white");
  MagickSetImageFormat(mw,"RGB");
  MagickSetImageDepth(mw,16);
  MagickSetImageType(mw,TrueColorType);

  MagickSetImagePixels(mw,0,0,Width,Height,"RGB",ShortPixel,(unsigned char*) m_Data.data());

  MagickSetImageDepth(mw,8);

  MagickSetImageCompression(mw, LZWCompression);

  bool Result = MagickWriteImage(mw, FileName);
  DestroyMagickWand(mw);
  return Result;
}
Exemplo n.º 18
0
G_MODULE_EXPORT void cb_image_save_ok_clicked(GtkButton *button)
{
  char *filename;
  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (camera_params.objects->imagesavedialog));
  g_print("Saving to Filename %s\n",filename);
  
  if(camera_params.wand_data.saving_wand)
  {
    MagickBooleanType status;
    status=MagickSetImageFormat(camera_params.wand_data.saving_wand,"PNG");
    if (status == MagickFalse)
      ThrowWandException(camera_params.wand_data.saving_wand);
    status=MagickWriteImage(camera_params.wand_data.saving_wand,filename);
    if (status == MagickFalse)
      ThrowWandException(camera_params.wand_data.saving_wand);
    DestroyMagickWand(camera_params.wand_data.saving_wand);
  }
  g_free (filename);


  camera_params.wand_data.saving_wand=NULL;
  gtk_widget_hide( camera_params.objects->imagesavedialog );
}
int convert_format (MagickWand *input, convert_t *opts) {
  if (opts->format < JPEG || opts->format > BMP) return MagickPass;
  return MagickSetImageFormat(input, formats[opts->format]);
}
unsigned char* generate_thumbnail( const void *image, const size_t size, size_t *new_size )
{
    MagickWand		*magick_wand, *magick_wand_canvas;
    PixelWand		*pixel_wand;
    unsigned int	cols, rows, ncols, nrows;
    unsigned char	*new_blob;

    // Initialize MagickWand:
    MagickWandGenesis();

    magick_wand = NewMagickWand();
    magick_wand_canvas = NewMagickWand();
    pixel_wand = NewPixelWand();



    // Read image from memory:
    DoMagick( magick_wand, MagickReadImageBlob( magick_wand, image, size ) );

    // If input consists of several images, we'll only take the first one:
    MagickResetIterator( magick_wand );
    MagickSetFirstIterator( magick_wand );

    // Get image size:
    cols = MagickGetImageWidth( magick_wand );
    rows = MagickGetImageHeight( magick_wand );

    printf("Image size: %ix%i\n", (int)cols, (int)rows);

    if (cols==0 || rows==0)
	{
	    fprintf(stderr, "generateThumbnail: Warning, imagesize==0, skipping image...\n");

            pixel_wand = DestroyPixelWand( pixel_wand );
	    magick_wand_canvas = DestroyMagickWand( magick_wand_canvas );
    	    magick_wand = DestroyMagickWand( magick_wand );
    	    MagickWandTerminus();
	    return NULL;
	}

    if (cols >= rows)
	{
	    ncols = 98;
	    nrows = (rows*98)/cols;
	}
    else
	{
	    nrows = 98;
	    ncols = (cols*98)/rows;
	}

    // Convert the image into a thumbnail:
    DoMagick( magick_wand, MagickThumbnailImage( magick_wand, ncols, nrows ) );


    PixelSetColor( pixel_wand, "#8f7f6f" );

    DoMagick( magick_wand, MagickBorderImage( magick_wand, pixel_wand, 1, 1 ) );

    DoMagick( magick_wand, MagickSetImageBackgroundColor( magick_wand, pixel_wand ) );


    PixelSetColor( pixel_wand, "white" );
    DoMagick( magick_wand_canvas, MagickNewImage( magick_wand_canvas, 100, 100, pixel_wand ) );

    DoMagick( magick_wand_canvas, MagickCompositeImage( magick_wand_canvas, magick_wand, OverCompositeOp, 49-(ncols/2), 49-(nrows/2) ) );

//    DoMagick( magick_wand_canvas, MagickWriteImage( magick_wand_canvas, "thumbnail.png" ) );
    DoMagick( magick_wand_canvas, MagickSetImageFormat( magick_wand_canvas, "PNG" ) );
    new_blob = MagickGetImageBlob( magick_wand_canvas, new_size );
// unsigned char *MagickGetImageBlob(MagickWand *wand,size_t *length)

    pixel_wand = DestroyPixelWand( pixel_wand );
    magick_wand = DestroyMagickWand( magick_wand );
    magick_wand_canvas = DestroyMagickWand( magick_wand_canvas );
    MagickWandTerminus();

    return new_blob;
}
Exemplo n.º 21
0
// Write Image
bool ptImage::ptGMCWriteImage(const char* FileName,
                              const short Format,
                              const int Quality,
                              const int Sampling,
                              const int Resolution,
                              const char* ColorProfileFileName,
                              const int Intent) {

  long unsigned int Width  = m_Width;
  long unsigned int Height = m_Height;

  MagickWand *mw;

  mw = NewMagickWand();
  MagickSetSize(mw, Width, Height);
  MagickReadImage(mw,"xc:white");
  MagickSetImageFormat(mw,"RGB");
  MagickSetImageDepth(mw,16);
  MagickSetImageType(mw,TrueColorType);

  MagickSetImagePixels(mw,0,0,Width,Height,"RGB",ShortPixel,(unsigned char*) m_Image);

  // Color profile
  // Color profile in PNG is not supported, due to limitations in imagemagick
  if (ColorProfileFileName != NULL) {
    FILE* pFile = fopen (ColorProfileFileName, "rb" );
    if (pFile==NULL) {
      ptLogError(ptError_FileOpen,FileName);
      exit(EXIT_FAILURE);
    }
    fseek (pFile , 0 , SEEK_END);
    long lSize = ftell (pFile);
    rewind (pFile);

    uint8_t* pchBuffer = (uint8_t*) CALLOC(lSize,sizeof(uint8_t));
    ptMemoryError(pchBuffer,__FILE__,__LINE__);

    size_t RV = fread (pchBuffer, 1, lSize, pFile);
    if (RV != (size_t) lSize) {
      ptLogError(ptError_FileOpen,FileName);
      exit(EXIT_FAILURE);
    }
    MagickSetImageProfile(mw,"ICC",pchBuffer,lSize);

    FCLOSE (pFile);
    FREE (pchBuffer);
  }
  // Redering intent
  switch(Intent) {
    case 0:
      MagickSetImageRenderingIntent(mw,PerceptualIntent);
      break;
    case 1:
      MagickSetImageRenderingIntent(mw,RelativeIntent);
      break;
    case 2:
      MagickSetImageRenderingIntent(mw,SaturationIntent);
      break;
    case 3:
      MagickSetImageRenderingIntent(mw,AbsoluteIntent);
      break;
    default:
      assert(0);
  }

  // Depth
  if ((Format==ptSaveFormat_TIFF8) ||
      (Format==ptSaveFormat_PPM8) ||
      (Format==ptSaveFormat_JPEG) ||
      (Format==ptSaveFormat_PNG)) {
    MagickSetImageDepth(mw,8);
  }

  // Jpeg Sampling
  double factors111[3] = {1.0,1.0,1.0};
  double factors211[3] = {2.0,1.0,1.0};
  if (Format==ptSaveFormat_JPEG) {
    if (Sampling==ptSaveSampling_111) {
      MagickSetSamplingFactors(mw,3,factors111);
    } else {
      MagickSetSamplingFactors(mw,3,factors211);
    }
  }

  // Quality
  if (Format==ptSaveFormat_PNG || Format==ptSaveFormat_PNG16)
    MagickSetCompressionQuality(mw, floor((double) Quality/10.0)*10+5);
  else
    MagickSetCompressionQuality(mw,Quality);

  // Compression
  if ((Format==ptSaveFormat_TIFF8) ||
      (Format==ptSaveFormat_TIFF16)) {
    MagickSetImageCompression(mw, LZWCompression);
  }

  // Resolution
  MagickSetImageUnits(mw, PixelsPerInchResolution);
  MagickSetImageResolution(mw, Resolution, Resolution);

  bool Result = MagickWriteImage(mw, FileName);
  DestroyMagickWand(mw);
  return Result;
}
Exemplo n.º 22
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 {
Exemplo n.º 23
0
Arquivo: zdb.c Projeto: haython/zimg
/**
 * @brief get_img_mode_db Get image from db mode backend.
 *
 * @param req zimg request struct
 * @param buff_ptr buff pointer
 * @param img_size buff size
 *
 * @return 1 for success and -1 for failed
 */
int get_img_mode_db(zimg_req_t *req, evhtp_request_t *request)
{
    int result = -1;
    char cache_key[CACHE_KEY_SIZE];
    char *img_format = NULL;
    char *buff_ptr = NULL;
    size_t img_size;

    MagickBooleanType status;
    MagickWand *magick_wand = NULL;

    bool got_rsp = true;
    bool got_color = false;

    LOG_PRINT(LOG_DEBUG, "get_img() start processing zimg request...");

    if(req->gray == 1)
    {
        gen_key(cache_key, req->md5, 4, req->width, req->height, req->proportion, req->gray);
    }
    else
    {
        if(req->proportion == 0 && req->width == 0 && req->height == 0)
        {
            gen_key(cache_key, req->md5, 0);
        }
        else
        {
            gen_key(cache_key, req->md5, 3, req->width, req->height, req->proportion);
        }
    }
    if(find_cache_bin(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
    {
        LOG_PRINT(LOG_DEBUG, "Hit Cache[Key: %s].", cache_key);
        goto done;
    }
    LOG_PRINT(LOG_DEBUG, "Start to Find the Image...");
    if(get_img_db(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
    {
        LOG_PRINT(LOG_DEBUG, "Get image [%s] from backend db succ.", cache_key);
        if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        goto done;
    }

    magick_wand = NewMagickWand();
    got_rsp = false;
    if(req->gray == 1)
    {
        gen_key(cache_key, req->md5, 3, req->width, req->height, req->proportion);
        if(find_cache_bin(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
        {
            LOG_PRINT(LOG_DEBUG, "Hit Color Image Cache[Key: %s, len: %d].", cache_key, img_size);
            status = MagickReadImageBlob(magick_wand, buff_ptr, img_size);
            free(buff_ptr);
            buff_ptr = NULL;
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Color Image Cache[Key: %s] is Bad. Remove.", cache_key);
                del_cache(req->thr_arg, cache_key);
            }
            else
            {
                got_color = true;
                LOG_PRINT(LOG_DEBUG, "Read Image from Color Image Cache[Key: %s, len: %d] Succ. Goto Convert.", cache_key, img_size);
                goto convert;
            }
        }
        if(get_img_db(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
        {
            LOG_PRINT(LOG_DEBUG, "Get color image [%s] from backend db.", cache_key);
            status = MagickReadImageBlob(magick_wand, buff_ptr, img_size);
            if(status == MagickTrue)
            {
                got_color = true;
                LOG_PRINT(LOG_DEBUG, "Read Image from Color Image[%s] Succ. Goto Convert.", cache_key);
                if(img_size < CACHE_MAX_SIZE)
                {
                    set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
                }
                free(buff_ptr);
                buff_ptr = NULL;
                goto convert;
            }
        }
    }

    gen_key(cache_key, req->md5, 0);
    if(find_cache_bin(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
    {
        LOG_PRINT(LOG_DEBUG, "Hit Cache[Key: %s].", cache_key);
    }
    else
    {
        if(get_img_db(req->thr_arg, cache_key, &buff_ptr, &img_size) == -1)
        {
            LOG_PRINT(LOG_DEBUG, "Get image [%s] from backend db failed.", cache_key);
            goto err;
        }
        else if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
    }

    status = MagickReadImageBlob(magick_wand, buff_ptr, img_size);
    free(buff_ptr);
    buff_ptr = NULL;
    if(status == MagickFalse)
    {
        ThrowWandException(magick_wand);
        del_cache(req->thr_arg, cache_key);
        LOG_PRINT(LOG_DEBUG, "Read image [%s] from blob failed.", cache_key);
        goto err;
    }

    if(req->width == 0 && req->height == 0)
    {
        LOG_PRINT(LOG_DEBUG, "Image [%s] needn't resize. Goto Convert.", cache_key);
        goto convert;
    }

    int width, height;
    width = req->width;
    height = req->height;
    float owidth = MagickGetImageWidth(magick_wand);
    float oheight = MagickGetImageHeight(magick_wand);
    if(width <= owidth && height <= oheight)
    {
        if(req->proportion == 1 || (req->proportion == 0 && req->width * req->height == 0))
        {
            if(req->height == 0)
            {
                height = width * oheight / owidth;
            }
            else
            {
                width = height * owidth / oheight;
            }
        }
        status = MagickResizeImage(magick_wand, width, height, LanczosFilter, 1.0);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Image[%s] Resize Failed!", cache_key);
            goto err;
        }

        LOG_PRINT(LOG_DEBUG, "Resize img succ.");
    }
    else
    {
        got_rsp = true;
        LOG_PRINT(LOG_DEBUG, "Args width/height is bigger than real size, return original image.");
    }

convert:

    //compress image
    if(got_color == false)
    {
        LOG_PRINT(LOG_DEBUG, "Start to Compress the Image!");
        img_format = MagickGetImageFormat(magick_wand);
        LOG_PRINT(LOG_DEBUG, "Image Format is %s", img_format);
        if(strcmp(img_format, "JPEG") != 0)
        {
            LOG_PRINT(LOG_DEBUG, "Convert Image Format from %s to JPEG.", img_format);
            status = MagickSetImageFormat(magick_wand, "JPEG");
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Image[%s] Convert Format Failed!", cache_key);
            }
            LOG_PRINT(LOG_DEBUG, "Compress Image with JPEGCompression");
            status = MagickSetImageCompression(magick_wand, JPEGCompression);
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Image[%s] Compression Failed!", cache_key);
            }
        }
        size_t quality = MagickGetImageCompressionQuality(magick_wand);
        LOG_PRINT(LOG_DEBUG, "Image Compression Quality is %u.", quality);
        if(quality > WAP_QUALITY)
        {
            quality = WAP_QUALITY;
        }
        LOG_PRINT(LOG_DEBUG, "Set Compression Quality to 75%.");
        status = MagickSetImageCompressionQuality(magick_wand, quality);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Set Compression Quality Failed!");
        }

        //strip image EXIF infomation
        LOG_PRINT(LOG_DEBUG, "Start to Remove Exif Infomation of the Image...");
        status = MagickStripImage(magick_wand);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Remove Exif Infomation of the ImageFailed!");
        }

        buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
        if(buff_ptr == NULL)
        {
            LOG_PRINT(LOG_DEBUG, "Magick Get Image Blob Failed!");
            goto err;
        }
        gen_key(cache_key, req->md5, 3, req->width, req->height, req->proportion);
        if(got_rsp == false)
        {
            save_img_db(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        if(req->gray == 1)
        {
            free(buff_ptr);
            buff_ptr = NULL;
        }
        else
        {
            goto done;
        }
    } 

    //gray image
    if(req->gray == 1)
    {
        LOG_PRINT(LOG_DEBUG, "Start to Remove Color!");
        status = MagickSetImageColorspace(magick_wand, GRAYColorspace);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Image[%s] Remove Color Failed!", cache_key);
            goto err;
        }
        LOG_PRINT(LOG_DEBUG, "Image Remove Color Finish!");


        buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
        if(buff_ptr == NULL)
        {
            LOG_PRINT(LOG_DEBUG, "Magick Get Image Blob Failed!");
            goto err;
        }
        gen_key(cache_key, req->md5, 4, req->width, req->height, req->proportion, req->gray);
        if(got_rsp == false)
        {
            save_img_db(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
    }

done:
    result = evbuffer_add(request->buffer_out, buff_ptr, img_size);
    if(result != -1)
    {
        result = 1;
    }

err:
    if(magick_wand)
    {
        magick_wand=DestroyMagickWand(magick_wand);
    }
    if(img_format)
        free(img_format);
    if(buff_ptr)
        free(buff_ptr);
    return result;
}
Exemplo n.º 24
0
apr_status_t
dims_format_operation (dims_request_rec *d, char *args, char **err) {
    MAGICK_CHECK(MagickSetImageFormat(d->wand, args), d);
    return DIMS_SUCCESS;
}
Exemplo n.º 25
0
Arquivo: zimg.c Projeto: Codefor/zimg
/**
 * @brief get_img The function of getting a image buffer and it's length.
 *
 * @param req The zimg_req_t from zhttp and it has the params of a request.
 * @param buff_ptr This function return image buffer in it.
 * @param img_size Get_img will change this number to return the size of image buffer.
 *
 * @return ZIMG_OK for success and ZIMG_ERR for fail.
 */
int get_img(zimg_req_t *req, char **buff_ptr, size_t *img_size)
{
    int result = -1;
    char *rsp_path = NULL;
    char *whole_path = NULL;
    char *orig_path = NULL;
    char *color_path = NULL;
    char *img_format = NULL;
    size_t len;
    int fd = -1;
    struct stat f_stat;

    MagickBooleanType status;
    MagickWand *magick_wand = NULL;

    LOG_PRINT(LOG_INFO, "get_img() start processing zimg request...");

    char *cache_key = (char *)malloc(strlen(req->md5) + 32);
    if(cache_key == NULL){
	LOG_PRINT(LOG_INFO, "malloc failed!");
	return ZIMG_ERR;
    }
    // to gen cache_key like this: img:926ee2f570dc50b2575e35a6712b08ce:0:0:1:0
    sprintf(cache_key, "img:%s:%d:%d:%d:%d", req->md5, req->width, req->height, req->proportion, req->gray);
    if(find_cache_bin(cache_key, buff_ptr, img_size) == 1){
	LOG_PRINT(LOG_INFO, "Hit Cache[Key: %s].", cache_key);
	//        sprintf(cache_key, "type:%s:%d:%d:%d:%d", req->md5, req->width, req->height, req->proportion, req->gray);
	//        if(find_cache(cache_key, img_format) == -1)
	//        {
	//            LOG_PRINT(LOG_WARNING, "Cannot Hit Type Cache[Key: %s]. Use jpeg As Default.", cache_key);
	//            strcpy(img_format, "jpeg");
	//        }
	free(cache_key);
	return ZIMG_OK;
    }
    free(cache_key);

    LOG_PRINT(LOG_INFO, "Start to Find the Image...");

    //check img dir
    // /1023/1023/xxxxxxxxxxxxxxx.png
    len = strlen(req->md5) + strlen(settings.img_path) + 12;
    whole_path = malloc(len);

    if (whole_path == NULL){
	LOG_PRINT(LOG_ERROR, "whole_path malloc failed!");
	return ZIMG_ERR;
    }

    int lvl1 = str_hash(req->md5);
    int lvl2 = str_hash(req->md5 + 3);
    sprintf(whole_path, "%s/%d/%d/%s", settings.img_path, lvl1, lvl2, req->md5);
    LOG_PRINT(LOG_INFO, "docroot: %s", settings.img_path);
    LOG_PRINT(LOG_INFO, "req->md5: %s", req->md5);
    LOG_PRINT(LOG_INFO, "whole_path: %s", whole_path);

    char name[128];
    if(req->proportion && req->gray)
	sprintf(name, "%d*%dpg", req->width, req->height);
    else if(req->proportion && !req->gray)
	sprintf(name, "%d*%dp", req->width, req->height);
    else if(!req->proportion && req->gray)
	sprintf(name, "%d*%dg", req->width, req->height);
    else
	sprintf(name, "%d*%d", req->width, req->height);

    orig_path = (char *)malloc(strlen(whole_path) + 6);
    sprintf(orig_path, "%s/0*0p", whole_path);
    LOG_PRINT(LOG_INFO, "0rig File Path: %s", orig_path);

    rsp_path = (char *)malloc(512);
    if(req->width == 0 && req->height == 0 && req->gray == 0)
    {
	LOG_PRINT(LOG_INFO, "Return original image.");
	strcpy(rsp_path, orig_path);
    }
    else
    {
	sprintf(rsp_path, "%s/%s", whole_path, name);
    }
    LOG_PRINT(LOG_INFO, "Got the rsp_path: %s", rsp_path);
    bool got_rsp = true;
    bool got_color = false;


    //status=MagickReadImage(magick_wand, rsp_path);
    if((fd = open(rsp_path, O_RDONLY)) == -1)
	//if(status == MagickFalse)
    {
	magick_wand = NewMagickWand();
	got_rsp = false;

	if(req->gray == 1)
	{
	    sprintf(cache_key, "img:%s:%d:%d:%d:0", req->md5, req->width, req->height, req->proportion);
	    if(find_cache_bin(cache_key, buff_ptr, img_size) == 1)
	    {
		LOG_PRINT(LOG_INFO, "Hit Color Image Cache[Key: %s, len: %d].", cache_key, *img_size);
		status = MagickReadImageBlob(magick_wand, *buff_ptr, *img_size);
		if(status == MagickFalse)
		{
		    LOG_PRINT(LOG_WARNING, "Color Image Cache[Key: %s] is Bad. Remove.", cache_key);
		    del_cache(cache_key);
		}
		else
		{
		    got_color = true;
		    LOG_PRINT(LOG_INFO, "Read Image from Color Image Cache[Key: %s, len: %d] Succ. Goto Convert.", cache_key, *img_size);
		    goto convert;
		}
	    }

	    len = strlen(rsp_path);
	    color_path = (char *)malloc(len);
	    strncpy(color_path, rsp_path, len);
	    color_path[len - 1] = '\0';
	    LOG_PRINT(LOG_INFO, "color_path: %s", color_path);
	    status=MagickReadImage(magick_wand, color_path);
	    if(status == MagickTrue)
	    {
		got_color = true;
		LOG_PRINT(LOG_INFO, "Read Image from Color Image[%s] Succ. Goto Convert.", color_path);
		*buff_ptr = (char *)MagickGetImageBlob(magick_wand, img_size);
		if(*img_size < CACHE_MAX_SIZE)
		{
		    set_cache_bin(cache_key, *buff_ptr, *img_size);
		    //                    img_format = MagickGetImageFormat(magick_wand);
		    //                    sprintf(cache_key, "type:%s:%d:%d:%d:0", req->md5, req->width, req->height, req->proportion);
		    //                    set_cache(cache_key, img_format);
		}

		goto convert;
	    }
	}

	// to gen cache_key like this: rsp_path-/926ee2f570dc50b2575e35a6712b08ce
	sprintf(cache_key, "img:%s:0:0:1:0", req->md5);
	if(find_cache_bin(cache_key, buff_ptr, img_size) == 1)
	{
	    LOG_PRINT(LOG_INFO, "Hit Orignal Image Cache[Key: %s].", cache_key);
	    status = MagickReadImageBlob(magick_wand, *buff_ptr, *img_size);
	    if(status == MagickFalse)
	    {
		LOG_PRINT(LOG_WARNING, "Open Original Image From Blob Failed! Begin to Open it From Disk.");
		ThrowWandException(magick_wand);
		del_cache(cache_key);
		status = MagickReadImage(magick_wand, orig_path);
		if(status == MagickFalse)
		{
		    ThrowWandException(magick_wand);
		    goto err;
		}
		else
		{
		    *buff_ptr = (char *)MagickGetImageBlob(magick_wand, img_size);
		    if(*img_size < CACHE_MAX_SIZE)
		    {
			set_cache_bin(cache_key, *buff_ptr, *img_size);
			//                        img_format = MagickGetImageFormat(magick_wand);
			//                        sprintf(cache_key, "type:%s:0:0:1:0", req->md5);
			//                        set_cache(cache_key, img_format);
		    }
		}
	    }
	}
	else
	{
	    LOG_PRINT(LOG_INFO, "Not Hit Original Image Cache. Begin to Open it.");
	    status = MagickReadImage(magick_wand, orig_path);
	    if(status == MagickFalse)
	    {
		ThrowWandException(magick_wand);
		goto err;
	    }
	    else
	    {
		*buff_ptr = (char *)MagickGetImageBlob(magick_wand, img_size);
		if(*img_size < CACHE_MAX_SIZE)
		{
		    set_cache_bin(cache_key, *buff_ptr, *img_size);
		    //                    img_format = MagickGetImageFormat(magick_wand);
		    //                    sprintf(cache_key, "type:%s:0:0:1:0", req->md5);
		    //                    set_cache(cache_key, img_format);
		}
	    }
	}
	int width, height;
	width = req->width;
	height = req->height;
	float owidth = MagickGetImageWidth(magick_wand);
	float oheight = MagickGetImageHeight(magick_wand);
	if(width <= owidth && height <= oheight)
	{
	    if(req->proportion == 1)
	    {
		if(req->width != 0 && req->height == 0)
		{
		    height = width * oheight / owidth;
		}
		//else if(height != 0 && width == 0)
		else
		{
		    width = height * owidth / oheight;
		}
	    }
	    status = MagickResizeImage(magick_wand, width, height, LanczosFilter, 1.0);
	    if(status == MagickFalse)
	    {
		LOG_PRINT(LOG_ERROR, "Image[%s] Resize Failed!", orig_path);
		goto err;
	    }
	    LOG_PRINT(LOG_INFO, "Resize img succ.");
	}
	/* this section can caculate the correct rsp_path, but not use, so I note them
	   else if(req->gray == true)
	   {
	   strcpy(rsp_path, orig_path);
	   rsp_path[strlen(orig_path)] = 'g';
	   rsp_path[strlen(orig_path) + 1] = '\0';
	   got_rsp = true;
	   LOG_PRINT(LOG_INFO, "Args width/height is bigger than real size, return original gray image.");
	   LOG_PRINT(LOG_INFO, "Original Gray Image: %s", rsp_path);
	   }
	 */
	else
	{
	    // Note this strcpy because rsp_path is not useful. We needn't to save the new image.
	    //strcpy(rsp_path, orig_path);
	    got_rsp = true;
	    LOG_PRINT(LOG_INFO, "Args width/height is bigger than real size, return original image.");
	}
    }
    else
    {
	fstat(fd, &f_stat);
	size_t rlen = 0;
	*img_size = f_stat.st_size;
	if(*img_size <= 0)
	{
	    LOG_PRINT(LOG_ERROR, "File[%s] is Empty.", rsp_path);
	    goto err;
	}
	if((*buff_ptr = (char *)malloc(*img_size)) == NULL)
	{
	    LOG_PRINT(LOG_ERROR, "buff_ptr Malloc Failed!");
	    goto err;
	}
	LOG_PRINT(LOG_INFO, "img_size = %d", *img_size);
	//*buff_ptr = (char *)MagickGetImageBlob(magick_wand, img_size);
	if((rlen = read(fd, *buff_ptr, *img_size)) == -1)
	{
	    LOG_PRINT(LOG_ERROR, "File[%s] Read Failed.", rsp_path);
	    LOG_PRINT(LOG_ERROR, "Error: %s.", strerror(errno));
	    goto err;
	}
	else if(rlen < *img_size)
	{
	    LOG_PRINT(LOG_ERROR, "File[%s] Read Not Compeletly.", rsp_path);
	    goto err;
	}
	goto done;
    }



convert:
    //gray image
    if(req->gray == true)
    {
	LOG_PRINT(LOG_INFO, "Start to Remove Color!");
	status = MagickSetImageColorspace(magick_wand, GRAYColorspace);
	if(status == MagickFalse)
	{
	    LOG_PRINT(LOG_ERROR, "Image[%s] Remove Color Failed!", orig_path);
	    goto err;
	}
	LOG_PRINT(LOG_INFO, "Image Remove Color Finish!");
    }

    if(got_color == false || (got_color == true && req->width == 0) )
    {
	//compress image
	LOG_PRINT(LOG_INFO, "Start to Compress the Image!");
	img_format = MagickGetImageFormat(magick_wand);
	LOG_PRINT(LOG_INFO, "Image Format is %s", img_format);
	if(strcmp(img_format, "JPEG") != 0)
	{
	    LOG_PRINT(LOG_INFO, "Convert Image Format from %s to JPEG.", img_format);
	    status = MagickSetImageFormat(magick_wand, "JPEG");
	    if(status == MagickFalse)
	    {
		LOG_PRINT(LOG_WARNING, "Image[%s] Convert Format Failed!", orig_path);
	    }
	    LOG_PRINT(LOG_INFO, "Compress Image with JPEGCompression");
	    status = MagickSetImageCompression(magick_wand, JPEGCompression);
	    if(status == MagickFalse)
	    {
		LOG_PRINT(LOG_WARNING, "Image[%s] Compression Failed!", orig_path);
	    }
	}
	size_t quality = MagickGetImageCompressionQuality(magick_wand) * 0.75;
	LOG_PRINT(LOG_INFO, "Image Compression Quality is %u.", quality);
	if(quality == 0)
	{
	    quality = 75;
	}
	LOG_PRINT(LOG_INFO, "Set Compression Quality to 75%.");
	status = MagickSetImageCompressionQuality(magick_wand, quality);
	if(status == MagickFalse)
	{
	    LOG_PRINT(LOG_WARNING, "Set Compression Quality Failed!");
	}

	//strip image EXIF infomation
	LOG_PRINT(LOG_INFO, "Start to Remove Exif Infomation of the Image...");
	status = MagickStripImage(magick_wand);
	if(status == MagickFalse)
	{
	    LOG_PRINT(LOG_WARNING, "Remove Exif Infomation of the ImageFailed!");
	}
    }
    *buff_ptr = (char *)MagickGetImageBlob(magick_wand, img_size);
    if(*buff_ptr == NULL)
    {
	LOG_PRINT(LOG_ERROR, "Magick Get Image Blob Failed!");
	goto err;
    }


done:
    if(*img_size < CACHE_MAX_SIZE)
    {
	// to gen cache_key like this: rsp_path-/926ee2f570dc50b2575e35a6712b08ce
	sprintf(cache_key, "img:%s:%d:%d:%d:%d", req->md5, req->width, req->height, req->proportion, req->gray);
	set_cache_bin(cache_key, *buff_ptr, *img_size);
	//        sprintf(cache_key, "type:%s:%d:%d:%d:%d", req->md5, req->width, req->height, req->proportion, req->gray);
	//        set_cache(cache_key, img_format);
    }

    result = 1;
    if(got_rsp == false)
    {
	LOG_PRINT(LOG_INFO, "Image[%s] is Not Existed. Begin to Save it.", rsp_path);
	result = 2;
    }
    else
	LOG_PRINT(LOG_INFO, "Image Needn't to Storage.", rsp_path);

err:
    if(fd != -1)
	close(fd);
    req->rsp_path = rsp_path;
    if(magick_wand)
    {
	magick_wand=DestroyMagickWand(magick_wand);
    }
    if(img_format)
	free(img_format);
    if(cache_key)
	free(cache_key);
    if (orig_path)
	free(orig_path);
    if (whole_path)
	free(whole_path);
    return result;
}
Exemplo n.º 26
0
/**
 * @brief convert convert image function
 *
 * @param im the image
 * @param req the zimg request
 *
 * @return 1 for OK and -1 for fail
 */
int convert(MagickWand *im, zimg_req_t *req)
{
    int result = 1, ret = -1;

    MagickResetIterator(im);
    MagickSetImageOrientation(im, TopLeftOrientation);

    int x = req->x, y = req->y, cols = req->width, rows = req->height;
    if (!(cols == 0 && rows == 0)) {
        /* crop and scale */
        if (x == -1 && y == -1) {
            LOG_PRINT(LOG_DEBUG, "proportion(im, %d, %d, %d)", req->proportion, cols, rows);
            ret = proportion(im, req->proportion, cols, rows);
            if (ret != MagickTrue) return -1;
        } else {
            LOG_PRINT(LOG_DEBUG, "crop(im, %d, %d, %d, %d)", x, y, cols, rows);
            ret = crop(im, x, y, cols, rows);
            if (ret != MagickTrue) return -1;
        }
    }

    /* rotate image */
    if (req->rotate != 0) {
        LOG_PRINT(LOG_DEBUG, "wi_rotate(im, %d)", req->rotate);
        PixelWand *background = NewPixelWand();
        if (background == NULL) return -1;
        ret = PixelSetColor(background, "white");
        if (ret != MagickTrue) {
            DestroyPixelWand(background);
            return -1;
        }
        ret = MagickRotateImage(im, background, req->rotate);
        LOG_PRINT(LOG_DEBUG, "rotate() ret = %d", ret);
        DestroyPixelWand(background);
        if (ret != MagickTrue) return -1;
    }

    /* set gray */
    if (req->gray == 1) {
        LOG_PRINT(LOG_DEBUG, "wi_gray(im)");
        //several ways to grayscale an image:
        //ret = MagickSetImageColorspace(im, GRAYColorspace);
        //ret = MagickQuantizeImage(im, 256, GRAYColorspace, 0, MagickFalse, MagickFalse);
        //ret = MagickSeparateImageChannel(im, GrayChannel);
        ret = MagickSetImageType(im, GrayscaleType);
        LOG_PRINT(LOG_DEBUG, "gray() ret = %d", ret);
        if (ret != MagickTrue) return -1;
    }

	/* set quality */
    /*
    int quality = 100;
    int im_quality = MagickGetImageCompressionQuality(im);
    im_quality = (im_quality == 0 ? 100 : im_quality);
    LOG_PRINT(LOG_DEBUG, "wi_quality = %d", im_quality);
    quality = req->quality < im_quality ? req->quality : im_quality;
    */
    LOG_PRINT(LOG_DEBUG, "wi_set_quality(im, %d)", req->quality);
    ret = MagickSetImageCompressionQuality(im, req->quality);
    if (ret != MagickTrue) return -1;

	/* set format */
    if (strncmp(req->fmt, "none", 4) != 0) {
        LOG_PRINT(LOG_DEBUG, "wi_set_format(im, %s)", req->fmt);
        ret = MagickSetImageFormat(im, req->fmt);
        if (ret != MagickTrue) return -1;
    }

    LOG_PRINT(LOG_DEBUG, "convert(im, req) %d", result);
	return result;
}
Exemplo n.º 27
0
/**
 * @brief get_img The function of getting a image buffer and it's length.
 *
 * @param req The zimg_req_t from zhttp and it has the params of a request.
 * @param buff_ptr This function return image buffer in it.
 * @param img_size Get_img will change this number to return the size of image buffer.
 *
 * @return 1 for success and -1 for fail.
 */
int get_img(zimg_req_t *req, evhtp_request_t *request)
{
    int result = -1;
    char cache_key[CACHE_KEY_SIZE];
    char *img_format = NULL;
    int fd = -1;
    struct stat f_stat;
    char *buff_ptr;
    size_t img_size;

    MagickBooleanType status;
    MagickWand *magick_wand = NULL;

    bool got_rsp = true;
    bool got_color = false;

    LOG_PRINT(LOG_DEBUG, "get_img() start processing zimg request...");

    // to gen cache_key like this: 926ee2f570dc50b2575e35a6712b08ce:0:0:1:0
    gen_key(cache_key, req->md5, 4, req->width, req->height, req->proportion, req->gray);
    if(find_cache_bin(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
    {
        LOG_PRINT(LOG_DEBUG, "Hit Cache[Key: %s].", cache_key);
        goto done;
    }
    LOG_PRINT(LOG_DEBUG, "Start to Find the Image...");

    char whole_path[512];
    int lvl1 = str_hash(req->md5);
    int lvl2 = str_hash(req->md5 + 3);
    snprintf(whole_path, 512, "%s/%d/%d/%s", settings.img_path, lvl1, lvl2, req->md5);
    LOG_PRINT(LOG_DEBUG, "docroot: %s", settings.img_path);
    LOG_PRINT(LOG_DEBUG, "req->md5: %s", req->md5);
    LOG_PRINT(LOG_DEBUG, "whole_path: %s", whole_path);

    char name[128];
    if(req->proportion && req->gray)
        snprintf(name, 128, "%d*%dpg", req->width, req->height);
    else if(req->proportion && !req->gray)
        snprintf(name, 128, "%d*%dp", req->width, req->height);
    else if(!req->proportion && req->gray)
        snprintf(name, 128, "%d*%dg", req->width, req->height);
    else
        snprintf(name, 128, "%d*%d", req->width, req->height);

    char color_name[128];
    if(req->proportion)
        snprintf(color_name, 128, "%d*%dp", req->width, req->height);
    else
        snprintf(color_name, 128, "%d*%d", req->width, req->height);

    char orig_path[512];
    snprintf(orig_path, strlen(whole_path) + 6, "%s/0*0", whole_path);
    LOG_PRINT(LOG_DEBUG, "0rig File Path: %s", orig_path);

    char rsp_path[512];
    if(req->width == 0 && req->height == 0 && req->proportion == 0 && req->gray == 0)
    {
        LOG_PRINT(LOG_DEBUG, "Return original image.");
        strncpy(rsp_path, orig_path, 512);
    }
    else
    {
        snprintf(rsp_path, 512, "%s/%s", whole_path, name);
    }
    LOG_PRINT(LOG_DEBUG, "Got the rsp_path: %s", rsp_path);

    char color_path[512];
    snprintf(color_path, 512, "%s/%s", whole_path, color_name);


    //status=MagickReadImage(magick_wand, rsp_path);
    if((fd = open(rsp_path, O_RDONLY)) == -1)
    {
        magick_wand = NewMagickWand();
        got_rsp = false;

        if(req->gray == 1)
        {
            gen_key(cache_key, req->md5, 3, req->width, req->height, req->proportion);
            if(find_cache_bin(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
            {
                LOG_PRINT(LOG_DEBUG, "Hit Color Image Cache[Key: %s, len: %d].", cache_key, img_size);
                status = MagickReadImageBlob(magick_wand, buff_ptr, img_size);
                free(buff_ptr);
                buff_ptr = NULL;
                if(status == MagickFalse)
                {
                    LOG_PRINT(LOG_DEBUG, "Color Image Cache[Key: %s] is Bad. Remove.", cache_key);
                    del_cache(req->thr_arg, cache_key);
                }
                else
                {
                    got_color = true;
                    LOG_PRINT(LOG_DEBUG, "Read Image from Color Image Cache[Key: %s, len: %d] Succ. Goto Convert.", cache_key, img_size);
                    goto convert;
                }
            }

            status=MagickReadImage(magick_wand, color_path);
            if(status == MagickTrue)
            {
                got_color = true;
                LOG_PRINT(LOG_DEBUG, "Read Image from Color Image[%s] Succ. Goto Convert.", rsp_path);
                buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
                if(img_size < CACHE_MAX_SIZE)
                {
                    set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
                }
                free(buff_ptr);
                buff_ptr = NULL;

                goto convert;
            }
        }

        // to gen cache_key like this: rsp_path-/926ee2f570dc50b2575e35a6712b08ce
        gen_key(cache_key, req->md5, 0);
        if(find_cache_bin(req->thr_arg, cache_key, &buff_ptr, &img_size) == 1)
        {
            LOG_PRINT(LOG_DEBUG, "Hit Orignal Image Cache[Key: %s].", cache_key);
            status = MagickReadImageBlob(magick_wand, buff_ptr, img_size);
            free(buff_ptr);
            buff_ptr = NULL;
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Open Original Image From Blob Failed! Begin to Open it From Disk.");
                ThrowWandException(magick_wand);
                del_cache(req->thr_arg, cache_key);
                status = MagickReadImage(magick_wand, orig_path);
                if(status == MagickFalse)
                {
                    ThrowWandException(magick_wand);
                    goto err;
                }
                else
                {
                    buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
                    if(img_size < CACHE_MAX_SIZE)
                    {
                        set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
                    }
                    free(buff_ptr);
                    buff_ptr = NULL;
                }
            }
        }
        else
        {
            LOG_PRINT(LOG_DEBUG, "Not Hit Original Image Cache. Begin to Open it.");
            status = MagickReadImage(magick_wand, orig_path);
            if(status == MagickFalse)
            {
                ThrowWandException(magick_wand);
                goto err;
            }
            else
            {
                buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
                if(img_size < CACHE_MAX_SIZE)
                {
                    set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
                }
                free(buff_ptr);
                buff_ptr = NULL;
            }
        }

        int width, height;
        width = req->width;
        height = req->height;
        if(width == 0 && height == 0)
        {
            LOG_PRINT(LOG_DEBUG, "Image[%s] needn't resize. Goto Convert.", orig_path);
            goto convert;
        }
        float owidth = MagickGetImageWidth(magick_wand);
        float oheight = MagickGetImageHeight(magick_wand);
        if(width <= owidth && height <= oheight)
        {
            if(req->proportion == 1 || (req->proportion == 0 && req->width * req->height == 0))
            {
                if(req->height == 0)
                {
                    height = width * oheight / owidth;
                }
                else
                {
                    width = height * owidth / oheight;
                }
            }
            status = MagickResizeImage(magick_wand, width, height, LanczosFilter, 1.0);
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Image[%s] Resize Failed!", orig_path);
                goto err;
            }
            LOG_PRINT(LOG_DEBUG, "Resize img succ.");
        }
        else
        {
            // Note this strcpy because rsp_path is not useful. We needn't to save the new image.
            got_rsp = true;
            LOG_PRINT(LOG_DEBUG, "Args width/height is bigger than real size, return original image.");
        }
    }
    else
    {
        fstat(fd, &f_stat);
        size_t rlen = 0;
        img_size = f_stat.st_size;
        if(img_size <= 0)
        {
            LOG_PRINT(LOG_DEBUG, "File[%s] is Empty.", rsp_path);
            goto err;
        }
        if((buff_ptr = (char *)malloc(img_size)) == NULL)
        {
            LOG_PRINT(LOG_DEBUG, "buff_ptr Malloc Failed!");
            goto err;
        }
        LOG_PRINT(LOG_DEBUG, "img_size = %d", img_size);
        if((rlen = read(fd, buff_ptr, img_size)) == -1)
        {
            LOG_PRINT(LOG_DEBUG, "File[%s] Read Failed.", rsp_path);
            LOG_PRINT(LOG_DEBUG, "Error: %s.", strerror(errno));
            goto err;
        }
        else if(rlen < img_size)
        {
            LOG_PRINT(LOG_DEBUG, "File[%s] Read Not Compeletly.", rsp_path);
            goto err;
        }
        if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        goto done;
    }

convert:

    if(got_color == false)
    {
        //compress image
        LOG_PRINT(LOG_DEBUG, "Start to Compress the Image!");
        img_format = MagickGetImageFormat(magick_wand);
        LOG_PRINT(LOG_DEBUG, "Image Format is %s", img_format);
        if(strcmp(img_format, "JPEG") != 0)
        {
            LOG_PRINT(LOG_DEBUG, "Convert Image Format from %s to JPEG.", img_format);
            status = MagickSetImageFormat(magick_wand, "JPEG");
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Image[%s] Convert Format Failed!", orig_path);
            }
            LOG_PRINT(LOG_DEBUG, "Compress Image with JPEGCompression");
            status = MagickSetImageCompression(magick_wand, JPEGCompression);
            if(status == MagickFalse)
            {
                LOG_PRINT(LOG_DEBUG, "Image[%s] Compression Failed!", orig_path);
            }
        }
        size_t quality = MagickGetImageCompressionQuality(magick_wand);
        LOG_PRINT(LOG_DEBUG, "Image Compression Quality is %u.", quality);
        if(quality > WAP_QUALITY)
        {
            quality = WAP_QUALITY;
        }
        LOG_PRINT(LOG_DEBUG, "Set Compression Quality to 75%.");
        status = MagickSetImageCompressionQuality(magick_wand, quality);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Set Compression Quality Failed!");
        }

        //strip image EXIF infomation
        LOG_PRINT(LOG_DEBUG, "Start to Remove Exif Infomation of the Image...");
        status = MagickStripImage(magick_wand);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Remove Exif Infomation of the ImageFailed!");
        }

        buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
        if(buff_ptr == NULL)
        {
            LOG_PRINT(LOG_DEBUG, "Magick Get Image Blob Failed!");
            goto err;
        }
        gen_key(cache_key, req->md5, 3, req->width, req->height, req->proportion);
        if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        if(got_rsp == false)
        {
            LOG_PRINT(LOG_DEBUG, "Color Image[%s] is Not Existed. Begin to Save it.", color_path);
            if(new_img(buff_ptr, img_size, color_path) == -1)
            {
                LOG_PRINT(LOG_DEBUG, "Color Image[%s] Save Failed!", color_path);
                LOG_PRINT(LOG_WARNING, "fail save %s", color_path);
            }
        }
        if(req->gray == 1)
        {
            free(buff_ptr);
            buff_ptr = NULL;
        }
        else
        {
            goto done;
        }
    }

    //gray image
    if(req->gray == 1)
    {
        LOG_PRINT(LOG_DEBUG, "Start to Remove Color!");
        status = MagickSetImageColorspace(magick_wand, GRAYColorspace);
        if(status == MagickFalse)
        {
            LOG_PRINT(LOG_DEBUG, "Image[%s] Remove Color Failed!", orig_path);
            goto err;
        }
        LOG_PRINT(LOG_DEBUG, "Image Remove Color Finish!");

        buff_ptr = (char *)MagickGetImageBlob(magick_wand, &img_size);
        if(buff_ptr == NULL)
        {
            LOG_PRINT(LOG_DEBUG, "Magick Get Image Blob Failed!");
            goto err;
        }
        gen_key(cache_key, req->md5, 4, req->width, req->height, req->proportion, req->gray);
        if(img_size < CACHE_MAX_SIZE)
        {
            set_cache_bin(req->thr_arg, cache_key, buff_ptr, img_size);
        }
        if(got_rsp == false)
        {
            if(new_img(buff_ptr, img_size, rsp_path) == -1)
            {
                LOG_PRINT(LOG_DEBUG, "New Image[%s] Save Failed!", rsp_path);
                LOG_PRINT(LOG_WARNING, "fail save %s", rsp_path);
            }
        }
        else
            LOG_PRINT(LOG_DEBUG, "Image Needn't to Storage.", rsp_path);
    }

done:
    result = evbuffer_add(request->buffer_out, buff_ptr, img_size);
    if(result != -1)
    {
        result = 1;
    }

err:
    if(fd != -1)
        close(fd);
    if(magick_wand)
    {
        magick_wand=DestroyMagickWand(magick_wand);
    }
    if(img_format)
        free(img_format);
    if(buff_ptr)
        free(buff_ptr);
    return result;
}
Exemplo n.º 28
0
int main(int argc,char **argv)
{
#define ThrowAPIException(wand) \
{ \
  description=MagickGetException(wand,&severity); \
  (void) FormatLocaleFile(stderr,"%s %s %lu %s\n",GetMagickModule(), \
    description); \
  description=(char *) MagickRelinquishMemory(description); \
  exit(-1); \
}

  static char
    CustomOption[] = "custom option",
    CustomProperty[] = "custom profile";

  static unsigned char
    sRGBProfile[] =
    {
      0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
      0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
      0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
      0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
      0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
      0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
      0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00,
      0x33, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00,
      0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00,
      0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04,
      0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02,
      0x18, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00,
      0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, 0x00,
      0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, 0x64, 0x6d, 0x6e, 0x64,
      0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64,
      0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, 0x76, 0x75,
      0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x76,
      0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24,
      0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00,
      0x14, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00,
      0x00, 0x24, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00,
      0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c,
      0x00, 0x00, 0x08, 0x0c, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04,
      0x3c, 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00,
      0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x74, 0x65, 0x78, 0x74, 0x00,
      0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
      0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
      0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63,
      0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
      0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45,
      0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
      0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39,
      0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58,
      0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a,
      0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00,
      0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85,
      0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00,
      0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
      0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
      0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
      0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
      0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31,
      0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, 0x66,
      0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6f,
      0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
      0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20,
      0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
      0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20,
      0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63,
      0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73,
      0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
      0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
      0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
      0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
      0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
      0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
      0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
      0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
      0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
      0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, 0x00,
      0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, 0x00, 0x03, 0x5c, 0x9e,
      0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, 0x00, 0x57,
      0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
      0x8f, 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00,
      0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05,
      0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00,
      0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b,
      0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, 0x00,
      0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
      0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00,
      0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9,
      0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00,
      0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0,
      0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01,
      0x01, 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f,
      0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01,
      0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67,
      0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01,
      0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9,
      0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, 0x01,
      0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
      0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02,
      0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a,
      0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02,
      0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb,
      0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03,
      0x2d, 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66,
      0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03,
      0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec,
      0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04,
      0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e,
      0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, 0x04,
      0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
      0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05,
      0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5,
      0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06,
      0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b,
      0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06,
      0xe3, 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d,
      0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07,
      0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b,
      0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08,
      0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7,
      0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, 0x09,
      0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
      0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a,
      0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5,
      0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b,
      0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8,
      0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c,
      0x5c, 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9,
      0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d,
      0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8,
      0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e,
      0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25,
      0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, 0x0f,
      0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
      0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11,
      0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa,
      0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12,
      0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03,
      0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13,
      0xc5, 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a,
      0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15,
      0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0,
      0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16,
      0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65,
      0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, 0x18,
      0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
      0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19,
      0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e,
      0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b,
      0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52,
      0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d,
      0x47, 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16,
      0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f,
      0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea,
      0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20,
      0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce,
      0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, 0x22,
      0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
      0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24,
      0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7,
      0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26,
      0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc,
      0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29,
      0x06, 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02,
      0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b,
      0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39,
      0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d,
      0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82,
      0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, 0x2f,
      0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
      0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32,
      0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46,
      0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34,
      0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2,
      0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37,
      0x24, 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50,
      0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39,
      0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef,
      0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c,
      0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1,
      0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, 0x3f,
      0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
      0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41,
      0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a,
      0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44,
      0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22,
      0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47,
      0xc0, 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d,
      0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a,
      0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a,
      0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d,
      0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49,
      0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, 0x51,
      0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
      0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54,
      0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2,
      0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57,
      0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a,
      0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a,
      0xf5, 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86,
      0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e,
      0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05,
      0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61,
      0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97,
      0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, 0x65,
      0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
      0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69,
      0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7,
      0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d,
      0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4,
      0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70,
      0xe0, 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6,
      0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74,
      0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b,
      0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78,
      0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5,
      0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, 0x7c,
      0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
      0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81,
      0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4,
      0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85,
      0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b,
      0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89,
      0x99, 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96,
      0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d,
      0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06,
      0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92,
      0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a,
      0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, 0x97,
      0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
      0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b,
      0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2,
      0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0,
      0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96,
      0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5,
      0x38, 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e,
      0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa,
      0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c,
      0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf,
      0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60,
      0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, 0xb4,
      0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
      0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9,
      0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7,
      0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe,
      0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec,
      0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3,
      0xd4, 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46,
      0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9,
      0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6,
      0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce,
      0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c,
      0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, 0xd4,
      0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
      0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9,
      0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a,
      0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf,
      0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53,
      0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5,
      0x84, 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32,
      0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb,
      0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28,
      0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1,
      0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34,
      0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, 0xf7,
      0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
      0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd,
      0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
    };


  char
    *description,
    **options,
    **profiles,
    **properties;

  const char
    *option,
    *property;

  DrawingWand
    *drawing_wand;

  ExceptionType
    severity;

  MagickWand
    *clone_wand,
    *magick_wand;

  PixelIterator
    *iterator;

  PixelWand
    *background,
    *border,
    *fill,
    **pixels;

  register ssize_t
    i;

  unsigned char
    *profile;

  unsigned int
    status;

  size_t
    columns,
    delay,
    length,
    number_options,
    number_profiles,
    number_properties,
    number_wands,
    rows;

  (void) argc;
  (void) argv;
  MagickWandGenesis();
  magick_wand=NewMagickWand();
  (void) MagickSetSize(magick_wand,640,480);
  (void) MagickGetSize(magick_wand,&columns,&rows);
  if ((columns != 640) || (rows != 480))
    {
      (void) FormatLocaleFile(stderr,"Unexpected magick wand size\n");
      exit(1);
    }
  (void) FormatLocaleFile(stdout,"Reading images...\n");
  {
    char
      *p,
      path[MaxTextExtent];

    path[0]=0;
    p=getenv("SRCDIR");
    if (p != (char *) NULL)
      {
        (void) strcpy(path,p);
        if (path[strlen(path)-1] != '/')
          (void) strcat(path,"/");
      }
    (void) strcat(path,"sequence.miff");
    status=MagickReadImage(magick_wand,path);
  }
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  if (MagickGetNumberImages(magick_wand) != 5)
    (void) FormatLocaleFile(stderr,"read %.20g images; expected 5\n",
      (double) MagickGetNumberImages(magick_wand));
  (void) FormatLocaleFile(stdout,"Iterate forward...\n");
  MagickResetIterator(magick_wand);
  while (MagickNextImage(magick_wand) != MagickFalse)
    (void) FormatLocaleFile(stdout,"index %.20g scene %.20g\n",(double)
      MagickGetIteratorIndex(magick_wand),(double)
      MagickGetImageScene(magick_wand));
  (void) FormatLocaleFile(stdout,"Iterate reverse...\n");
  while (MagickPreviousImage(magick_wand) != MagickFalse)
    (void) FormatLocaleFile(stdout,"index %.20g scene %.20g\n",(double)
      MagickGetIteratorIndex(magick_wand),(double)
      MagickGetImageScene(magick_wand));
  (void) FormatLocaleFile(stdout,"Remove scene 1...\n");
  (void) MagickSetIteratorIndex(magick_wand,1);
  clone_wand=MagickGetImage(magick_wand);
  status=MagickRemoveImage(magick_wand);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  MagickResetIterator(magick_wand);
  while (MagickNextImage(magick_wand) != MagickFalse)
    (void) FormatLocaleFile(stdout,"index %.20g scene %.20g\n",(double)
      MagickGetIteratorIndex(magick_wand),(double)
      MagickGetImageScene(magick_wand));
  (void) FormatLocaleFile(stdout,"Insert scene 1 back in sequence...\n");
  (void) MagickSetIteratorIndex(magick_wand,0);
  status=MagickAddImage(magick_wand,clone_wand);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  MagickResetIterator(magick_wand);
  while (MagickNextImage(magick_wand) != MagickFalse)
    (void) FormatLocaleFile(stdout,"index %.20g scene %.20g\n",(double)
      MagickGetIteratorIndex(magick_wand),(double)
      MagickGetImageScene(magick_wand));
  (void) FormatLocaleFile(stdout,"Set scene 2 to scene 1...\n");
  (void) MagickSetIteratorIndex(magick_wand,2);
  status=MagickSetImage(magick_wand,clone_wand);
  clone_wand=DestroyMagickWand(clone_wand);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  MagickResetIterator(magick_wand);
  while (MagickNextImage(magick_wand) != MagickFalse)
    (void) FormatLocaleFile(stdout,"index %.20g scene %.20g\n",(double)
      MagickGetIteratorIndex(magick_wand),(double)
      MagickGetImageScene(magick_wand));
  (void) FormatLocaleFile(stdout,"Apply image processing options...\n");
  status=MagickCropImage(magick_wand,60,60,10,10);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  MagickResetIterator(magick_wand);
  background=NewPixelWand();
  status=PixelSetColor(background,"#000000");
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  status=MagickRotateImage(magick_wand,background,90.0);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  border=NewPixelWand();
  (void) PixelSetColor(background,"green");
  (void) PixelSetColor(border,"black");
  status=MagickFloodfillPaintImage(magick_wand,CompositeChannels,background,
    0.01*QuantumRange,border,0,0,MagickFalse);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  background=DestroyPixelWand(background);
  border=DestroyPixelWand(border);
  drawing_wand=NewDrawingWand();
  (void) PushDrawingWand(drawing_wand);
  (void) DrawRotate(drawing_wand,45);
  (void) DrawSetFontSize(drawing_wand,18);
  fill=NewPixelWand();
  (void) PixelSetColor(fill,"green");
  (void) DrawSetFillColor(drawing_wand,fill);
  fill=DestroyPixelWand(fill);
  (void) DrawAnnotation(drawing_wand,15,5,(const unsigned char *) "Magick");
  (void) PopDrawingWand(drawing_wand);
  (void) MagickSetIteratorIndex(magick_wand,1);
  status=MagickDrawImage(magick_wand,drawing_wand);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  status=MagickAnnotateImage(magick_wand,drawing_wand,70,5,90,"Image");
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  drawing_wand=DestroyDrawingWand(drawing_wand);
  {
    unsigned char
      pixels[27],
      primary_colors[27] =
      {
          0,   0,   0,
          0,   0, 255,
          0, 255,   0,
          0, 255, 255,
        255, 255, 255,
        255,   0,   0,
        255,   0, 255,
        255, 255,   0,
        128, 128, 128,
      };

    (void) MagickSetIteratorIndex(magick_wand,2);
    status=MagickImportImagePixels(magick_wand,10,10,3,3,"RGB",CharPixel,
      primary_colors);
    if (status == MagickFalse)
      ThrowAPIException(magick_wand);
    status=MagickExportImagePixels(magick_wand,10,10,3,3,"RGB",CharPixel,
      pixels);
    if (status == MagickFalse)
      ThrowAPIException(magick_wand);
    for (i=0; i < 9; i++)
      if (pixels[i] != primary_colors[i])
        {
          (void) FormatLocaleFile(stderr,
            "Get pixels does not match set pixels\n");
          exit(1);
        }
  }
  (void) MagickSetIteratorIndex(magick_wand,3);
  status=MagickResizeImage(magick_wand,50,50,UndefinedFilter,1.0);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  MagickResetIterator(magick_wand);
  while (MagickNextImage(magick_wand) != MagickFalse)
  {
    (void) MagickSetImageDepth(magick_wand,8);
    (void) MagickSetImageCompression(magick_wand,RLECompression);
  }
  MagickResetIterator(magick_wand);
  (void) MagickSetIteratorIndex(magick_wand,4);
  (void) FormatLocaleFile(stdout,
    "Utilitize pixel iterator to draw diagonal...\n");
  iterator=NewPixelIterator(magick_wand);
  if (iterator == (PixelIterator *) NULL)
    ThrowAPIException(magick_wand);
  pixels=PixelGetNextIteratorRow(iterator,&number_wands);
  for (i=0; pixels != (PixelWand **) NULL; i++)
  {
    (void) PixelSetColor(pixels[i],"#224466");
    (void) PixelSyncIterator(iterator);
    pixels=PixelGetNextIteratorRow(iterator,&number_wands);
  }
  (void) PixelSyncIterator(iterator);
  iterator=DestroyPixelIterator(iterator);
  (void) FormatLocaleFile(stdout,"Write to wandtest_out.miff...\n");
  status=MagickWriteImages(magick_wand,"wandtest_out.miff",MagickTrue);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  (void) FormatLocaleFile(stdout,
    "Change image format from \"MIFF\" to \"GIF\"...\n");
  status=MagickSetImageFormat(magick_wand,"GIF");
  if (status == MagickFalse)
     ThrowAPIException(magick_wand);
  (void) FormatLocaleFile(stdout,"Set delay between frames to %d seconds...\n",
    WandDelay);
  status=MagickSetImageDelay(magick_wand,100*WandDelay);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  delay=MagickGetImageDelay(magick_wand);
  if (delay != (100*WandDelay))
    {
      (void) FormatLocaleFile(stderr,"Get delay does not match set delay\n");
      exit(1);
    }
  (void) FormatLocaleFile(stdout,"Write to wandtest_out_0.gif...\n");
  status=MagickWriteImages(magick_wand,"wandtest_out.gif",MagickTrue);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  (void) FormatLocaleFile(stdout,"Set, list, get, and delete wand option...\n");
  status=MagickSetOption(magick_wand,"wand:custom-option",CustomOption);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  option=MagickGetOption(magick_wand,"wand:custom-option");
  if ((option == (const char *) NULL) ||
      (strlen(option) != strlen(CustomOption)) ||
      (memcmp(option,CustomOption,strlen(option)) != 0))
    {
      (void) FormatLocaleFile(stderr,"Option does not match\n");
      exit(1);
    }
  options=MagickGetOptions(magick_wand,"*",&number_options);
  if (options != (char **) NULL)
    {
      for (i=0; i < (ssize_t) number_options; i++)
      {
        (void) FormatLocaleFile(stdout,"  %s\n",options[i]);
        options[i]=(char *) MagickRelinquishMemory(options[i]);
      }
      options=(char **) MagickRelinquishMemory(options);
    }
  status=MagickDeleteOption(magick_wand,"wand:custom-option");
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  (void) FormatLocaleFile(stdout,
    "Set, list, get, and delete wand property...\n");
  status=MagickSetImageProperty(magick_wand,"wand:custom-property",
    CustomProperty);
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  property=MagickGetImageProperty(magick_wand,"wand:custom-property");
  if ((property == (const char *) NULL) ||
      (strlen(property) != strlen(CustomProperty)) ||
      (memcmp(property,CustomProperty,strlen(property)) != 0))
    {
      (void) FormatLocaleFile(stderr,"Property does not match\n");
      exit(1);
    }
  properties=MagickGetImageProperties(magick_wand,"*",&number_properties);
  if (properties != (char **) NULL)
    {
      for (i=0; i < (ssize_t) number_properties; i++)
      {
        (void) FormatLocaleFile(stdout,"  %s\n",properties[i]);
        properties[i]=(char *) MagickRelinquishMemory(properties[i]);
      }
      properties=(char **) MagickRelinquishMemory(properties);
    }
  status=MagickDeleteImageProperty(magick_wand,"wand:custom-property");
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  (void) FormatLocaleFile(stdout,
    "Set, list, get, and remove sRGB color profile...\n");
  status=MagickSetImageProfile(magick_wand,"sRGB",sRGBProfile,
    sizeof(sRGBProfile));
  if (status == MagickFalse)
    ThrowAPIException(magick_wand);
  profile=(unsigned char *) MagickGetImageProfile(magick_wand,"sRGB",&length);
  if ((profile == (unsigned char *) NULL) || (length != sizeof(sRGBProfile)) ||
      (memcmp(profile,sRGBProfile,length) != 0))
    {
      (void) FormatLocaleFile(stderr,"Profile does not match\n");
      exit(1);
    }
  profile=(unsigned char *) MagickRelinquishMemory(profile);
  profiles=MagickGetImageProfiles(magick_wand,"*",&number_profiles);
  if (profiles != (char **) NULL)
    {
      for (i=0; i < (ssize_t) number_profiles; i++)
      {
        (void) FormatLocaleFile(stdout,"  %s\n",profiles[i]);
        profiles[i]=(char *) MagickRelinquishMemory(profiles[i]);
      }
      profiles=(char **) MagickRelinquishMemory(profiles);
    }
  profile=(unsigned char *) MagickRemoveImageProfile(magick_wand,"sRGB",
    &length);
  if ((profile == (unsigned char *) NULL) || (length != sizeof(sRGBProfile)) ||
      (memcmp(profile,sRGBProfile,length) != 0))
    {
      (void) FormatLocaleFile(stderr,"Profile does not match\n");
      exit(1);
    }
  profile=(unsigned char *) MagickRelinquishMemory(profile);
  magick_wand=DestroyMagickWand(magick_wand);
  (void) FormatLocaleFile(stdout,"Wand tests pass.\n");
  return(0);
}
Exemplo n.º 29
0
/* gcc -o imagick imagick-landscape-3d.c -Wall -Werror -I/usr/include/ImageMagick -lMagickWand */
int main()
{
  MagickWand *mw, *canvas;
  PixelWand  *pw;
  DrawingWand *line;
  size_t w, h, offset;
  int x, y, r, g, b, grey, lh;
  MagickBooleanType mbt;

  MagickWandGenesis();  /* startup */

  mw = NewMagickWand();

  mbt = MagickReadImage(mw, PNG_IN_FILE);
  assert(mbt == MagickTrue);
  w = MagickGetImageWidth(mw);
  h = MagickGetImageHeight(mw);

  pw = NewPixelWand();
  PixelSetColor(pw, "transparent");

  mbt = MagickShearImage(mw, pw, 45, 0);
  assert(mbt == MagickTrue);

  w = MagickGetImageWidth(mw);
  h = MagickGetImageHeight(mw);

  mbt = MagickScaleImage(mw, w, h/2);
  assert(mbt = MagickTrue);

  w = MagickGetImageWidth(mw);
  h = MagickGetImageHeight(mw);

  canvas = NewMagickWand();
  MagickGetImagePixelColor(mw, 0, 0, pw);
  MagickNewImage(canvas, w, h*2, pw);

  offset = h;
  for (x = 0; x < w; ++x) {
    line = NewDrawingWand();
    lh = 0;
    for (y = h-1; y >= 0; --y) {
      if (MagickGetImagePixelColor(mw, x, y, pw) == MagickFalse) continue;
      r = 255 * PixelGetRed(pw);
      g = 255 * PixelGetGreen(pw);
      b = 255 * PixelGetBlue(pw);

      grey = (r + g + b)/5;
      if (lh == 0 || lh < grey) {
        DrawSetFillColor(line, pw);
        DrawSetStrokeColor(line, pw);
        DrawLine(line, x, y + offset - lh, x, y - grey + offset);
        lh = grey;
      }
      lh--;
    }

    MagickDrawImage(canvas, line);
    DestroyDrawingWand(line);
  }

  MagickScaleImage(canvas, w - h, h * 2);
  
  mbt = MagickSetImageFormat(canvas, "png");
  assert(mbt == MagickTrue);
  mbt = MagickWriteImage(canvas, PNG_OUT_FILE);
  assert(mbt == MagickTrue);

  pw = DestroyPixelWand(pw);
  mw = DestroyMagickWand(mw);
  canvas = DestroyMagickWand(canvas);
  
  MagickWandTerminus(); /* shutdown */

  return 0;
}