Image *get_blue_channe_image(Image *img) { unsigned int i = 0; unsigned int j = 0; PixelPacket *px_original; PixelPacket *px_new; Image *new_img; ExceptionInfo exception; ImageInfo *new_img_info; GetExceptionInfo(&exception); if ((new_img_info = CloneImageInfo((ImageInfo *)NULL)) == NULL) { CatchException(&exception); DestroyImageInfo(new_img_info); return (NULL); } new_img_info->colorspace = RGBColorspace; new_img = AllocateImage(new_img_info); new_img->rows = img->rows; new_img->columns = img->columns; if ((px_original = GetImagePixelsEx(img, 0, 0, img->columns, img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } if ((px_new = SetImagePixelsEx(new_img, 0, 0, new_img->columns, new_img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } while (i < img->rows) { j = 0; while (j < img->columns) { px_new[(new_img->columns * i) + j].red = 0; px_new[(new_img->columns * i) + j].blue = px_original[(img->columns * i) + j].blue; px_new[(new_img->columns * i) + j].green = 0; j++; } i++; } SyncImagePixels(new_img); DestroyImageInfo(new_img_info); return (new_img); }
unsigned long *HalfImage(unsigned long *image,int colums,int rows) { #define Minify(weight) \ total.red+=(weight)*(r->red); \ total.green+=(weight)*(r->green); \ total.blue+=(weight)*(r->blue); \ total.opacity+=(weight)*(r->opacity); \ r++; unsigned long *minify_image; long y; /* Initialize minified image. */ minify_image= image; /* Reduce each row. */ { unsigned long row_count=0,zero=0; float red,green,blue,opacity; zero=0; for (y=0; y < (long) minify_image->rows; y++) { DoublePixelPacket total; register const PixelPacket *p, *r; register long x; register PixelPacket *q; MagickBool thread_status; p=AcquireImagePixels(image,-2,2*(y-1),image->columns+4,4,exception); q=SetImagePixelsEx(minify_image,0,y,minify_image->columns,1,exception); for (x=0; x < columns/2; x++) { /* Compute weighted average of target pixel color components. */ total=zero; r=p; Minify(3.0); Minify(7.0); Minify(7.0); Minify(3.0); r=p+(image->columns+4); Minify(7.0); Minify(15.0); Minify(15.0); Minify(7.0); r=p+2*(image->columns+4); Minify(7.0); Minify(15.0); Minify(15.0); Minify(7.0); r=p+3*(image->columns+4); Minify(3.0); Minify(7.0); Minify(7.0); Minify(3.0); q->red=(Quantum) (total.red/128.0+0.5); q->green=(Quantum) (total.green/128.0+0.5); q->blue=(Quantum) (total.blue/128.0+0.5); q->opacity=(Quantum) (total.opacity/128.0+0.5); p+=2; q++; } if (!SyncImagePixelsEx(minify_image,exception)) thread_status=MagickFail; #if defined(HAVE_OPENMP) # pragma omp critical (GM_MinifyImage) #endif { row_count++; if (QuantumTick(row_count,image->rows)) if (!MagickMonitorFormatted(row_count,image->rows,exception, MinifyImageText,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } } minify_image->is_grayscale=image->is_grayscale; return(minify_image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P i x e l I t e r a t e T r i p l e M o d i f y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PixelIterateTripleModify() iterates through pixel regions of three images % and invokes a user-provided callback function (of type % PixelIteratorTripleModifyCallback) for each row of pixels. The first two % images are read-only, while the third image is read-write for update. % Access of the first two images is done lock-step using the same coordinates. % This is useful to support operations such as image differencing. % % The format of the PixelIterateTripleModify method is: % % MagickPassFail PixelIterateTripleModify( % PixelIteratorTripleModifyCallback call_back, % const PixelIteratorOptions *options, % const char *description, % void *mutable_data, % const void *immutable_data, % const unsigned long columns, % const unsigned long rows, % const Image *source1_image, % const Image *source2_image, % const long source_x, % const long source_y, % Image *update_image, % const long update_x, % const long update_y, % ExceptionInfo *exception) % % A description of each parameter follows: % % o call_back: A user-provided C callback function which reads from % a region of source pixels and updates a region of destination pixels. % % o options: Pixel iterator execution options (may be NULL). % % o description: textual description of operation being performed. % % o mutable_data: User-provided mutable context data. % % o immutable_data: User-provided immutable context data. % % o columns: Width of pixel region % % o rows: Height of pixel region % % o source1_image: The address of the constant source 1 Image. % % o source2_image: The address of the constant source 2 Image. % % o source_x: The horizontal ordinate of the top left corner of the source regions. % % o source_y: The vertical ordinate of the top left corner of the source regions. % % o update_image: The address of the update Image. % % o update_x: The horizontal ordinate of the top left corner of the update region. % % o update_y: The vertical ordinate of the top left corner of the update region. % % o exception: If an error is reported, this argument is updated with the reason. % */ static MagickPassFail PixelIterateTripleImplementation(PixelIteratorTripleModifyCallback call_back, const PixelIteratorOptions *options, const char *description, void *mutable_data, const void *immutable_data, const unsigned long columns, const unsigned long rows, const Image *source1_image, const Image *source2_image, const long source_x, const long source_y, Image *update_image, const long update_x, const long update_y, ExceptionInfo *exception, MagickBool set) { MagickPassFail status = MagickPass; register long row; unsigned long row_count=0; int max_threads; max_threads=omp_get_max_threads(); (void) SetRegionThreads(max_threads,options,columns,rows); #if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,1) shared(row_count, status) #endif for (row=0; row < (long) rows; row++) { MagickBool thread_status; const PixelPacket *source1_pixels, *source2_pixels; const IndexPacket *source1_indexes, *source2_indexes; PixelPacket *update_pixels; IndexPacket *update_indexes; long source_row, update_row; thread_status=status; if (thread_status == MagickFail) continue; source_row=source_y+row; update_row=update_y+row; /* First image (read only). */ source1_pixels=AcquireImagePixels(source1_image, source_x, source_row, columns, 1, exception); if (!source1_pixels) thread_status=MagickFail; source1_indexes=AccessImmutableIndexes(source1_image); /* Second image (read only). */ source2_pixels=AcquireImagePixels(source2_image, source_x, source_row, columns, 1, exception); if (!source2_pixels) thread_status=MagickFail; source2_indexes=AccessImmutableIndexes(source2_image); /* Third image (read/write). */ if (set) update_pixels=SetImagePixelsEx(update_image, update_x, update_row, columns, 1, exception); else update_pixels=GetImagePixelsEx(update_image, update_x, update_row, columns, 1, exception); if (!update_pixels) { thread_status=MagickFail; CopyException(exception,&update_image->exception); } update_indexes=AccessMutableIndexes(update_image); if (thread_status != MagickFail) status=(call_back)(mutable_data,immutable_data, source1_image,source1_pixels,source1_indexes, source2_image,source2_pixels,source2_indexes, update_image,update_pixels,update_indexes, columns,exception); if (!SyncImagePixelsEx(update_image,exception)) thread_status=MagickFail; #if defined(HAVE_OPENMP) # pragma omp critical (GM_PixelIterateTripleImplementation) #endif { row_count++; if (QuantumTick(row_count,rows)) if (!MagickMonitorFormatted(row_count,rows,exception,description, source1_image->filename, source2_image->filename, update_image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } omp_set_num_threads(max_threads); return (status); }
MagickExport MagickPassFail GradientImage(Image *image, const PixelPacket *start_color, const PixelPacket *stop_color) { const unsigned long image_rows=image->rows, image_columns=image->columns; long y; unsigned long row_count=0; MagickPassFail status=MagickPass; /* Determine (Hue, Saturation, Brightness) gradient. */ assert(image != (const Image *) NULL); assert(image->signature == MagickSignature); assert(start_color != (const PixelPacket *) NULL); assert(stop_color != (const PixelPacket *) NULL); /* Generate gradient pixels. */ #if defined(HAVE_OPENMP) # pragma omp parallel for shared(row_count, status) #endif for (y=0; y < (long) image->rows; y++) { MagickPassFail thread_status; register long x; register PixelPacket *q; #if defined(HAVE_OPENMP) # pragma omp critical (GM_GradientImage) #endif thread_status=status; if (thread_status == MagickFail) continue; q=SetImagePixelsEx(image,0,y,image->columns,1,&image->exception); if (q == (PixelPacket *) NULL) thread_status=MagickFail; if (q != (PixelPacket *) NULL) { for (x=0; x < (long) image->columns; x++) { BlendCompositePixel(&q[x],start_color,stop_color,(double) MaxRGB*(y*image_columns+x)/(image_columns*image_rows)); } if (!SyncImagePixelsEx(image,&image->exception)) thread_status=MagickFail; } #if defined(HAVE_OPENMP) # pragma omp critical (GM_GradientImage) #endif { row_count++; if (QuantumTick(row_count,image->rows)) if (!MagickMonitorFormatted(row_count,image->rows,&image->exception, GradientImageText,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } if (IsGray(*start_color) && IsGray(*stop_color)) image->is_grayscale=MagickTrue; if (IsMonochrome(*start_color) && ColorMatch(start_color,stop_color)) image->is_monochrome=MagickTrue; return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d S C T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadSCTImage reads a Scitex image file and returns it. It allocates % the memory necessary for the new Image structure and returns a pointer to % the new image. % % The format of the ReadSCTImage method is: % % Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadSCTImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or % if the image cannot be read. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o exception: return any errors or warnings in this structure. % % */ static Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception) { char buffer[768], magick[2]; Image *image; long y; register long x; register PixelPacket *q; int c; unsigned int status; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Read control block. */ do { if (ReadBlob(image,80,(char *) buffer) != 80) break; if (ReadBlob(image,2,(char *) magick) != 2) break; if ((LocaleNCompare((char *) magick,"CT",2) != 0) && (LocaleNCompare((char *) magick,"LW",2) != 0) && (LocaleNCompare((char *) magick,"BM",2) != 0) && (LocaleNCompare((char *) magick,"PG",2) != 0) && (LocaleNCompare((char *) magick,"TX",2) != 0)) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); if ((LocaleNCompare((char *) magick,"LW",2) == 0) || (LocaleNCompare((char *) magick,"BM",2) == 0) || (LocaleNCompare((char *) magick,"PG",2) == 0) || (LocaleNCompare((char *) magick,"TX",2) == 0)) ThrowReaderException(CoderError,OnlyContinuousTonePictureSupported,image); if (ReadBlob(image,174,(char *) buffer) != 174) break; if (ReadBlob(image,768,(char *) buffer) != 768) break; /* Read parameter block. */ if (ReadBlob(image,32,(char *) buffer) != 32) break; if (ReadBlob(image,14,(char *) buffer) != 14) break; image->rows=MagickAtoL(buffer) & 0x7FFFFFFF; if (ReadBlob(image,14,(char *) buffer) != 14) break; image->columns=MagickAtoL(buffer) & 0x7FFFFFFF; if (ReadBlob(image,196,(char *) buffer) != 196) break; if (ReadBlob(image,768,(char *) buffer) != 768) break; image->colorspace=CMYKColorspace; } while (0); if (EOFBlob(image)) ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->ping) { CloseBlob(image); return(image); } if (CheckImagePixelLimits(image, exception) != MagickPass) ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); /* Convert SCT raster image to pixel packets. */ for (y=0; y < (long) image->rows; y++) { q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if ((c = ReadBlobByte(image)) == EOF) break; q->red=(Quantum) (MaxRGB-ScaleCharToQuantum(c)); q++; } if ((image->columns % 2) != 0) if (ReadBlobByte(image) == EOF) /* pad */ break; q=GetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if ((c = ReadBlobByte(image)) == EOF) break; q->green=(Quantum) (MaxRGB-ScaleCharToQuantum(c)); q++; } if ((image->columns % 2) != 0) if (ReadBlobByte(image) == EOF) /* pad */ break; q=GetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if ((c = ReadBlobByte(image)) == EOF) break; q->blue=(Quantum) (MaxRGB-ScaleCharToQuantum(c)); q++; } if ((image->columns % 2) != 0) if (ReadBlobByte(image) == EOF) /* pad */ break; q=GetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if ((c = ReadBlobByte(image)) == EOF) break; q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(c)); q++; } if (!SyncImagePixelsEx(image,exception)) break; if ((image->columns % 2) != 0) if (ReadBlobByte(image) == EOF) /* pad */ break; if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText, image->filename, image->columns,image->rows)) break; if (EOFBlob(image)) break; } if (EOFBlob(image)) ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, image->filename); CloseBlob(image); return(image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d T I M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadTIMImage reads a PSX TIM image file and returns it. It % allocates the memory necessary for the new Image structure and returns a % pointer to the new image. % % Contributed by [email protected]. % % The format of the ReadTIMImage method is: % % Image *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadTIMImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or % if the image cannot be read. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o exception: return any errors or warnings in this structure. % % */ static Image *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception) { typedef struct _TIMInfo { unsigned long id, flag; } TIMInfo; TIMInfo tim_info; Image *image; int bits_per_pixel, has_clut; long y; register IndexPacket *indexes; register long x; register PixelPacket *q; register long i; register unsigned char *p; unsigned char *tim_data, *tim_pixels; unsigned short word; unsigned int status; size_t bytes_per_line, image_size; unsigned long height, pixel_mode, width; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Determine if this is a TIM file. */ tim_info.id=ReadBlobLSBLong(image); do { /* Verify TIM identifier. */ if (tim_info.id != 0x00000010) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); tim_info.flag=ReadBlobLSBLong(image); has_clut=!!(tim_info.flag & (1 << 3)); pixel_mode=tim_info.flag & 0x07; switch ((int) pixel_mode) { case 0: bits_per_pixel=4; break; case 1: bits_per_pixel=8; break; case 2: bits_per_pixel=16; break; case 3: bits_per_pixel=24; break; default: bits_per_pixel=4; break; } image->depth=8; if (has_clut) { unsigned char *tim_colormap; /* Read TIM raster colormap. */ (void)ReadBlobLSBLong(image); (void)ReadBlobLSBShort(image); (void)ReadBlobLSBShort(image); /* width= */ (void)ReadBlobLSBShort(image); /* height= */ (void)ReadBlobLSBShort(image); if (!AllocateImageColormap(image,pixel_mode == 1 ? 256 : 16)) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); tim_colormap=MagickAllocateMemory(unsigned char *,image->colors*2); if (tim_colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); (void) ReadBlob(image,2*image->colors,(char *) tim_colormap); p=tim_colormap; for (i=0; i < (long) image->colors; i++) { word=(*p++); word|=(unsigned short) (*p++ << 8U); image->colormap[i].blue=ScaleCharToQuantum(ScaleColor5to8((word >> 10U) & 0x1fU)); image->colormap[i].green=ScaleCharToQuantum(ScaleColor5to8((word >> 5U) & 0x1fU)); image->colormap[i].red=ScaleCharToQuantum(ScaleColor5to8(word & 0x1fU)); } MagickFreeMemory(tim_colormap); } /* Read image data. */ (void) ReadBlobLSBLong(image); (void) ReadBlobLSBShort(image); (void) ReadBlobLSBShort(image); if (EOFBlob(image)) ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); width=ReadBlobLSBShort(image); height=ReadBlobLSBShort(image); image_size=MagickArraySize(2,MagickArraySize(width,height)); bytes_per_line=MagickArraySize(width,2); width=(unsigned long)(MagickArraySize(width,16))/bits_per_pixel; /* Initialize image structure. */ image->columns=width; image->rows=height; if (image_info->ping && (image_info->subrange != 0)) if (image->scene >= (image_info->subimage+image_info->subrange-1)) break; if (CheckImagePixelLimits(image, exception) != MagickPass) ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); tim_data=MagickAllocateMemory(unsigned char *,image_size); if (tim_data == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); (void) ReadBlob(image,image_size,(char *) tim_data); tim_pixels=tim_data; /* Convert TIM raster image to pixel packets. */ switch (bits_per_pixel) { case 4: { /* Convert PseudoColor scanline. */ for (y=(long) image->rows-1; y >= 0; y--) { q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=AccessMutableIndexes(image); p=tim_pixels+y*bytes_per_line; for (x=0; x < ((long) image->columns-1); x+=2) { indexes[x]=(*p) & 0xf; indexes[x+1]=(*p >> 4) & 0xf; p++; } if ((image->columns % 2) != 0) { indexes[x]=(*p >> 4) & 0xf; p++; } if (!SyncImagePixelsEx(image,exception)) break; if (QuantumTick(y,image->rows)) { status=MagickMonitorFormatted(image->rows-y-1,image->rows, exception,LoadImageText, image->filename, image->columns,image->rows); if (status == False) break; } } break; } case 8: { /* Convert PseudoColor scanline. */ for (y=(long) image->rows-1; y >= 0; y--) { q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=AccessMutableIndexes(image); p=tim_pixels+y*bytes_per_line; for (x=0; x < (long) image->columns; x++) indexes[x]=(*p++); if (!SyncImagePixelsEx(image,exception)) break; if (QuantumTick(y,image->rows)) { status=MagickMonitorFormatted(image->rows-y-1,image->rows, exception,LoadImageText, image->filename, image->columns,image->rows); if (status == False) break; } } break; } case 16: { /* Convert DirectColor scanline. */ for (y=(long) image->rows-1; y >= 0; y--) { p=tim_pixels+y*bytes_per_line; q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { word=(*p++); word|=(*p++ << 8); q->blue=ScaleCharToQuantum(ScaleColor5to8((word >> 10) & 0x1f)); q->green=ScaleCharToQuantum(ScaleColor5to8((word >> 5) & 0x1f)); q->red=ScaleCharToQuantum(ScaleColor5to8(word & 0x1f)); q++; } if (!SyncImagePixelsEx(image,exception)) break; if (QuantumTick(y,image->rows)) { status=MagickMonitorFormatted(image->rows-y-1,image->rows, exception,LoadImageText, image->filename, image->columns,image->rows); if (status == False) break; } } break; } case 24: { /* Convert DirectColor scanline. */ for (y=(long) image->rows-1; y >= 0; y--) { p=tim_pixels+y*bytes_per_line; q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { q->red=ScaleCharToQuantum(*p++); q->green=ScaleCharToQuantum(*p++); q->blue=ScaleCharToQuantum(*p++); q++; } if (!SyncImagePixelsEx(image,exception)) break; if (QuantumTick(y,image->rows)) { status=MagickMonitorFormatted(image->rows-y-1,image->rows, exception,LoadImageText, image->filename, image->columns,image->rows); if (status == False) break; } } break; } default: ThrowReaderException(CorruptImageError,ImproperImageHeader,image) } if (image->storage_class == PseudoClass) (void) SyncImage(image); MagickFreeMemory(tim_pixels); if (EOFBlob(image)) { ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, image->filename); break; } /* Proceed to next image. */ tim_info.id=ReadBlobLSBLong(image); if (tim_info.id == 0x00000010) { /* Allocate next image structure. */ AllocateNextImage(image_info,image); if (image->next == (Image *) NULL) { DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image), exception,LoadImagesText, image->filename); if (status == False) break; } } while (tim_info.id == 0x00000010);
static Image *ReadIdentityImage(const ImageInfo *image_info, ExceptionInfo *exception) { #define IdentityImageText "[%s] Generating Hald CLUT identity image..." Image *image; unsigned long cube_size; long order, y; unsigned long row_count=0; unsigned int status=MagickPass; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=(Image *) NULL; order=8; if (image_info->filename[0] != '\0') order=MagickAtoL(image_info->filename); if (order < 2) order=8; image=AllocateImage(image_info); cube_size=order*order; image->columns=image->rows=order*order*order; #if defined(HAVE_OPENMP) # if defined(TUNE_OPENMP) # pragma omp parallel for schedule(runtime) shared(row_count, status) # else # pragma omp parallel for shared(row_count, status) # endif #endif for (y=0; y < (long) image->rows; y += order) { MagickPassFail thread_status; register PixelPacket *q; #if defined(HAVE_OPENMP) # pragma omp critical (GM_IdentityImage) #endif thread_status=status; if (thread_status == MagickFail) continue; q=SetImagePixelsEx(image,0,y,image->columns,order,&image->exception); if (q == (PixelPacket *) NULL) thread_status=MagickFail; if (q != (PixelPacket *) NULL) { double value; unsigned int red, green, blue; blue=y/order; for(green = 0; green < cube_size; green++) { for(red = 0; red < cube_size; red++) { value=MaxRGBDouble * (double)red / (double)(cube_size - 1); q->red = RoundDoubleToQuantum(value); value = MaxRGBDouble * (double)green / (double)(cube_size - 1); q->green = RoundDoubleToQuantum(value); value = MaxRGBDouble * (double)blue / (double)(cube_size - 1); q->blue = RoundDoubleToQuantum(value); q->opacity = OpaqueOpacity; q++; } } if (!SyncImagePixelsEx(image,&image->exception)) thread_status=MagickFail; } #if defined(HAVE_OPENMP) # pragma omp critical (GM_IdentityImage) #endif { row_count++; if (QuantumTick(row_count,image->rows)) if (!MagickMonitorFormatted(row_count,image->rows,&image->exception, IdentityImageText,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } if (status == MagickFail) { DestroyImage(image); image=(Image *) NULL; } return(image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % A v e r a g e I m a g e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The Average() method takes a set of images and averages them together. % Each image in the set must have the same width and height. Average() % returns a single image with each corresponding pixel component of % each image averaged. On failure, a NULL image is returned and % exception describes the reason for the failure. % % The format of the AverageImage method is: % % Image *AverageImages(Image *image,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: The image sequence. % % o exception: Return any errors or warnings in this structure. % % */ MagickExport Image *AverageImages(const Image *image,ExceptionInfo *exception) { ThreadViewDataSet *pixels_sums; Image *average_image; const Image *last_image; long y; unsigned long row_count=0; double number_scenes; unsigned long number_pixels; MagickPassFail status=MagickPass; /* Ensure the image are the same size. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); if (image->next == (Image *) NULL) ThrowImageException3(ImageError,ImageSequenceIsRequired, UnableToAverageImage); { const Image *next; for (next=image; next != (Image *) NULL; next=next->next) { if ((next->columns != image->columns) || (next->rows != image->rows)) ThrowImageException3(OptionError,UnableToAverageImageSequence, ImageWidthsOrHeightsDiffer); } } /* Allocate sum accumulation buffer. */ number_pixels=image->columns; pixels_sums=AllocateThreadViewDataArray(image,exception,number_pixels, sizeof(DoublePixelPacket)); if (pixels_sums == (ThreadViewDataSet *) NULL) ThrowImageException3(ResourceLimitError,MemoryAllocationFailed, UnableToAverageImageSequence); /* Initialize average next attributes. */ average_image=CloneImage(image,image->columns,image->rows,True,exception); if (average_image == (Image *) NULL) { DestroyThreadViewDataSet(pixels_sums); return((Image *) NULL); } average_image->storage_class=DirectClass; number_scenes=(double) GetImageListLength(image); last_image=GetLastImageInList(image); #if defined(HAVE_OPENMP) # pragma omp parallel for schedule(dynamic) shared(row_count, status) #endif for (y=0; y < (long) image->rows; y++) { register DoublePixelPacket *pixels_sum; const Image *next; register const PixelPacket *p; register long x; MagickBool thread_status; thread_status=status; if (thread_status == MagickFail) continue; pixels_sum=AccessThreadViewData(pixels_sums); /* Compute sum over each pixel color component. */ for (next=image; next != (Image *) NULL; next=next->next) { ViewInfo *next_view; next_view=OpenCacheView((Image *) next); if (next_view == (ViewInfo *) NULL) thread_status=MagickFail; if (next_view != (ViewInfo *) NULL) { p=AcquireCacheViewPixels(next_view,0,y,next->columns,1,exception); if (p == (const PixelPacket *) NULL) thread_status=MagickFail; if (p != (const PixelPacket *) NULL) { if (next == image) { for (x=0; x < (long) next->columns; x++) { pixels_sum[x].red=p[x].red; pixels_sum[x].green=p[x].green; pixels_sum[x].blue=p[x].blue; pixels_sum[x].opacity=p[x].opacity; } } else { for (x=0; x < (long) next->columns; x++) { pixels_sum[x].red+=p[x].red; pixels_sum[x].green+=p[x].green; pixels_sum[x].blue+=p[x].blue; pixels_sum[x].opacity+=p[x].opacity; } } } CloseCacheView(next_view); } } /* Average next pixels. */ if (thread_status != MagickFail) { register PixelPacket *q; q=SetImagePixelsEx(average_image,0,y,average_image->columns,1,exception); if (q == (PixelPacket *) NULL) thread_status=MagickFail; if (q != (PixelPacket *) NULL) { for (x=0; x < (long) average_image->columns; x++) { q[x].red=(Quantum) (pixels_sum[x].red/number_scenes+0.5); q[x].green=(Quantum) (pixels_sum[x].green/number_scenes+0.5); q[x].blue=(Quantum) (pixels_sum[x].blue/number_scenes+0.5); q[x].opacity=(Quantum) (pixels_sum[x].opacity/number_scenes+0.5); } if (!SyncImagePixelsEx(average_image,exception)) thread_status=MagickFail; } } #if defined(HAVE_OPENMP) # pragma omp critical (GM_AverageImages) #endif { row_count++; if (QuantumTick(row_count,average_image->rows)) if (!MagickMonitorFormatted(row_count,average_image->rows,exception, "[%s,...,%s] Average image sequence...", image->filename,last_image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } DestroyThreadViewDataSet(pixels_sums); if (status == MagickFail) { DestroyImage(average_image); average_image=(Image *) NULL; } return(average_image); }
static Image *IntegralRotateImage(const Image *image,unsigned int rotations, ExceptionInfo *exception) { char message[MaxTextExtent]; Image *rotate_image; RectangleInfo page; long tile_width_max, tile_height_max; MagickPassFail status=MagickPass; /* Initialize rotated image attributes. */ assert(image != (Image *) NULL); page=image->page; rotations%=4; { /* Clone appropriately to create rotate image. */ unsigned long clone_columns=0, clone_rows=0; switch (rotations) { case 0: clone_columns=0; clone_rows=0; break; case 2: clone_columns=image->columns; clone_rows=image->rows; break; case 1: case 3: clone_columns=image->rows; clone_rows=image->columns; break; } rotate_image=CloneImage(image,clone_columns,clone_rows,True,exception); if (rotate_image == (Image *) NULL) return((Image *) NULL); if (rotations != 0) if (ModifyCache(rotate_image,exception) != MagickPass) { DestroyImage(rotate_image); return (Image *) NULL; } } tile_height_max=tile_width_max=2048/sizeof(PixelPacket); /* 2k x 2k = 4MB */ if ((rotations == 1) || (rotations == 3)) { /* Allow override of tile geometry for testing. */ const char * value; if (!GetPixelCacheInCore(image) || !GetPixelCacheInCore(rotate_image)) tile_height_max=tile_width_max=8192/sizeof(PixelPacket); /* 8k x 8k = 64MB */ if ((value=getenv("MAGICK_ROTATE_TILE_GEOMETRY"))) { double width, height; if (GetMagickDimension(value,&width,&height,NULL,NULL) == 2) { tile_height_max=(unsigned long) height; tile_width_max=(unsigned long) width; } } } /* Integral rotate the image. */ switch (rotations) { case 0: { /* Rotate 0 degrees (nothing more to do). */ (void) strlcpy(message,"[%s] Rotate: 0 degrees...",sizeof(message)); if (!MagickMonitorFormatted(image->rows-1,image->rows,exception, message,image->filename)) status=MagickFail; break; } case 1: { /* Rotate 90 degrees. */ magick_int64_t tile; magick_uint64_t total_tiles; long tile_y; (void) strlcpy(message,"[%s] Rotate: 90 degrees...",sizeof(message)); total_tiles=(((image->rows/tile_height_max)+1)* ((image->columns/tile_width_max)+1)); tile=0; #if defined(IntegralRotateImageUseOpenMP) # if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,1) shared(status, tile) # endif #endif for (tile_y=0; tile_y < (long) image->rows; tile_y+=tile_height_max) { long tile_x; MagickPassFail thread_status; thread_status=status; if (thread_status == MagickFail) continue; for (tile_x=0; tile_x < (long) image->columns; tile_x+=tile_width_max) { long dest_tile_x, dest_tile_y; long tile_width, tile_height; const PixelPacket *tile_pixels; long y; /* Compute image region corresponding to tile. */ if ((unsigned long) tile_x+tile_width_max > image->columns) tile_width=(tile_width_max-(tile_x+tile_width_max-image->columns)); else tile_width=tile_width_max; if ((unsigned long) tile_y+tile_height_max > image->rows) tile_height=(tile_height_max-(tile_y+tile_height_max-image->rows)); else tile_height=tile_height_max; /* Acquire tile */ tile_pixels=AcquireImagePixels(image,tile_x,tile_y, tile_width,tile_height,exception); if (tile_pixels == (const PixelPacket *) NULL) { thread_status=MagickFail; break; } /* Compute destination tile coordinates. */ dest_tile_x=rotate_image->columns-(tile_y+tile_height); dest_tile_y=tile_x; /* Rotate tile */ for (y=0; y < tile_width; y++) { register const PixelPacket *p; register PixelPacket *q; register const IndexPacket *indexes; IndexPacket *rotate_indexes; register long x; q=SetImagePixelsEx(rotate_image,dest_tile_x,dest_tile_y+y, tile_height,1,exception); if (q == (PixelPacket *) NULL) { thread_status=MagickFail; break; } /* DirectClass pixels */ p=tile_pixels+(tile_height-1)*tile_width + y; for (x=tile_height; x != 0; x--) { *q = *p; q++; p-=tile_width; } /* Indexes */ indexes=AccessImmutableIndexes(image); if (indexes != (IndexPacket *) NULL) { rotate_indexes=AccessMutableIndexes(rotate_image); if (rotate_indexes != (IndexPacket *) NULL) { register IndexPacket *iq; register const IndexPacket *ip; iq=rotate_indexes; ip=indexes+(tile_height-1)*tile_width + y; for (x=tile_height; x != 0; x--) { *iq = *ip; iq++; ip -= tile_width; } } } if (!SyncImagePixelsEx(rotate_image,exception)) { thread_status=MagickFail; break; } } #if defined(IntegralRotateImageUseOpenMP) # if defined(HAVE_OPENMP) # pragma omp critical (GM_IntegralRotateImage) # endif #endif { tile++; if (QuantumTick(tile,total_tiles)) if (!MagickMonitorFormatted(tile,total_tiles,exception, message,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } } Swap(page.width,page.height); Swap(page.x,page.y); page.x=(long) (page.width-rotate_image->columns-page.x); break; } case 2: { /* Rotate 180 degrees. */ long y; unsigned long row_count=0; (void) strlcpy(message,"[%s] Rotate: 180 degrees...",sizeof(message)); #if defined(IntegralRotateImageUseOpenMP) # if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,8) shared(row_count, status) # endif #endif for (y=0; y < (long) image->rows; y++) { register const PixelPacket *p; register PixelPacket *q; register const IndexPacket *indexes; IndexPacket *rotate_indexes; register long x; MagickPassFail thread_status; thread_status=status; if (thread_status == MagickFail) continue; p=AcquireImagePixels(image,0,y,image->columns,1,exception); q=SetImagePixelsEx(rotate_image,0,(long) (image->rows-y-1), image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) thread_status=MagickFail; if (thread_status != MagickFail) { q+=image->columns; indexes=AccessImmutableIndexes(image); rotate_indexes=AccessMutableIndexes(rotate_image); if ((indexes != (IndexPacket *) NULL) && (rotate_indexes != (IndexPacket *) NULL)) for (x=0; x < (long) image->columns; x++) rotate_indexes[image->columns-x-1]=indexes[x]; for (x=0; x < (long) image->columns; x++) *--q=(*p++); if (!SyncImagePixelsEx(rotate_image,exception)) thread_status=MagickFail; } #if defined(IntegralRotateImageUseOpenMP) # if defined(HAVE_OPENMP) # pragma omp critical (GM_IntegralRotateImage) # endif #endif { row_count++; if (QuantumTick(row_count,image->rows)) if (!MagickMonitorFormatted(row_count,image->rows,exception, message,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } page.x=(long) (page.width-rotate_image->columns-page.x); page.y=(long) (page.height-rotate_image->rows-page.y); break; } case 3: { /* Rotate 270 degrees. */ magick_int64_t tile; magick_uint64_t total_tiles; long tile_y; (void) strlcpy(message,"[%s] Rotate: 270 degrees...",sizeof(message)); total_tiles=(((image->rows/tile_height_max)+1)* ((image->columns/tile_width_max)+1)); tile=0; #if defined(IntegralRotateImageUseOpenMP) # if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,1) shared(status, tile) # endif #endif for (tile_y=0; tile_y < (long) image->rows; tile_y+=tile_height_max) { long tile_x; MagickPassFail thread_status; thread_status=status; if (thread_status == MagickFail) continue; for (tile_x=0; tile_x < (long) image->columns; tile_x+=tile_width_max) { long tile_width, tile_height; long dest_tile_x, dest_tile_y; long y; const PixelPacket *tile_pixels; /* Compute image region corresponding to tile. */ if ((unsigned long) tile_x+tile_width_max > image->columns) tile_width=(tile_width_max-(tile_x+tile_width_max-image->columns)); else tile_width=tile_width_max; if ((unsigned long) tile_y+tile_height_max > image->rows) tile_height=(tile_height_max-(tile_y+tile_height_max-image->rows)); else tile_height=tile_height_max; /* Acquire tile */ tile_pixels=AcquireImagePixels(image,tile_x,tile_y, tile_width,tile_height,exception); if (tile_pixels == (const PixelPacket *) NULL) { thread_status=MagickFail; break; } /* Compute destination tile coordinates. */ dest_tile_x=tile_y; dest_tile_y=rotate_image->rows-(tile_x+tile_width); /* Rotate tile */ for (y=0; y < tile_width; y++) { register const PixelPacket *p; register PixelPacket *q; register const IndexPacket *indexes; register long x; IndexPacket *rotate_indexes; q=SetImagePixelsEx(rotate_image,dest_tile_x,dest_tile_y+y, tile_height,1,exception); if (q == (PixelPacket *) NULL) { thread_status=MagickFail; break; } /* DirectClass pixels */ p=tile_pixels+(tile_width-1-y); for (x=tile_height; x != 0; x--) { *q = *p; q++; p += tile_width; } /* Indexes */ indexes=AccessImmutableIndexes(image); if (indexes != (IndexPacket *) NULL) { rotate_indexes=AccessMutableIndexes(rotate_image); if (rotate_indexes != (IndexPacket *) NULL) { register IndexPacket *iq; register const IndexPacket *ip; iq=rotate_indexes; ip=indexes+(tile_width-1-y); for (x=tile_height; x != 0; x--) { *iq = *ip; iq++; ip += tile_width; } } } if (!SyncImagePixelsEx(rotate_image,exception)) { thread_status=MagickFail; break; } } #if defined(IntegralRotateImageUseOpenMP) # if defined(HAVE_OPENMP) # pragma omp critical (GM_IntegralRotateImage) # endif #endif { tile++; if (QuantumTick(tile,total_tiles)) if (!MagickMonitorFormatted(tile,total_tiles,exception, message,image->filename)) thread_status=MagickFail; } if (thread_status == MagickFail) { status=MagickFail; break; } } } Swap(page.width,page.height); Swap(page.x,page.y); page.y=(long) (page.height-rotate_image->rows-page.y); break; } } rotate_image->page=page; rotate_image->is_grayscale=image->is_grayscale; rotate_image->is_monochrome=image->is_monochrome; return(rotate_image); }
Image *apply_green_contrast(Image *img, unsigned char min, unsigned char max) { unsigned int i = 0; unsigned int j = 0; PixelPacket *px_original; PixelPacket *px_new; Image *new_img; ExceptionInfo exception; ImageInfo *new_img_info; unsigned char pixel_value; unsigned int height = img->rows; unsigned int width = img->columns; unsigned int dataset_min = 255; unsigned int dataset_max = 0; GetExceptionInfo(&exception); if ((new_img_info = CloneImageInfo((ImageInfo *)NULL)) == NULL) { CatchException(&exception); DestroyImageInfo(new_img_info); return (NULL); } new_img_info->colorspace = RGBColorspace; new_img = AllocateImage(new_img_info); new_img->rows = img->rows; new_img->columns = img->columns; if ((px_original = GetImagePixelsEx(img, 0, 0, img->columns, img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } if ((px_new = SetImagePixelsEx(new_img, 0, 0, new_img->columns, new_img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } while (i < height) { j = 0; while (j < width) { pixel_value = px_original[(width * i) + j].green; if (pixel_value < dataset_min) dataset_min = pixel_value; if (pixel_value > dataset_max) dataset_max = pixel_value; j++; } i++; } i = 0; while (i < height) { j = 0; while (j < width) { pixel_value = px_original[(width * i) + j].green; pixel_value = (pixel_value >= 255 ? 254 : pixel_value); pixel_value = get_contrasted_value(min, max, dataset_min, dataset_max, pixel_value); px_new[(width * i) + j].red = 0; px_new[(width * i) + j].green = pixel_value; px_new[(width * i) + j].blue = 0; j++; } i++; } SyncImagePixels(new_img); DestroyImageInfo(new_img_info); return(new_img); }
Image *substract_grayscale_to_original(Image *img, Image *gray_img, int min, int max) { unsigned int i = 0; unsigned int j = 0; PixelPacket *px_original; PixelPacket *px_gray; PixelPacket *px_new; Image *new_img; ExceptionInfo exception; ImageInfo *new_img_info; GetExceptionInfo(&exception); if ((new_img_info = CloneImageInfo((ImageInfo *)NULL)) == NULL) { CatchException(&exception); DestroyImageInfo(new_img_info); return (NULL); } new_img_info->colorspace = RGBColorspace; new_img = AllocateImage(new_img_info); new_img->rows = img->rows; new_img->columns = img->columns; if ((px_original = GetImagePixelsEx(img, 0, 0, img->columns, img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } if ((px_gray = GetImagePixelsEx(gray_img, 0, 0, img->columns, img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } if ((px_new = SetImagePixelsEx(new_img, 0, 0, new_img->columns, new_img->rows, &exception)) == NULL) { DestroyImage(new_img); CatchException(&exception); return (NULL); } while (i < img->rows) { j = 0; while (j < img->columns) { if(px_gray[(new_img->columns * i) + j].red > max || px_gray[(new_img->columns * i) + j].red < min) { px_new[(new_img->columns * i) + j].red = 0; px_new[(new_img->columns * i) + j].blue = 0; px_new[(new_img->columns * i) + j].green = 0; } else { px_new[(new_img->columns * i) + j].red = px_original[(new_img->columns * i) + j].red; px_new[(new_img->columns * i) + j].blue = px_original[(new_img->columns * i) + j].blue; px_new[(new_img->columns * i) + j].green = px_original[(new_img->columns * i) + j].green; } j++; } i++; } SyncImagePixels(new_img); DestroyImageInfo(new_img_info); return (new_img); }