1 /* Copyright (C) kaerou 2021.
2 ** Distributed under the Boost Software License, Version 1.0.
3 ** (See accompanying file LICENSE_1_0.txt or copy at
4 ** https://www.boost.org/LICENSE_1_0.txt)
6 module magickd
.core
.c
.image
;
10 import core
.stdc
.config
: c_long
, c_ulong
;
11 import core
.stdc
.stdio
: FILE
;
13 import magickd
.core
.c
.common
;
14 import magickd
.core
.c
.colorspace
;
15 import magickd
.core
.c
.error
;
16 import magickd
.core
.c
.timer
;
19 @nogc @system extern(C
):
21 enum QuantumDepth
= 16;
23 static if (QuantumDepth
== 8)
25 enum MaxColormapSize
= 256U;
28 enum MaxMapFloat
= 255.0f;
29 enum MaxMapDouble
= 255.0;
31 enum MaxRGBFloat
= 255.0f;
32 enum MaxRGBDouble
= 255.0;
33 /* TODO: Scale functions */
34 alias Quantum
= ubyte;
36 else static if (QuantumDepth
== 16)
38 enum MaxColormapSize
= 65536U;
40 enum MaxMapDepth
= 16;
41 enum MaxMapFloat
= 65535.0f;
42 enum MaxMapDouble
= 65535.0;
44 enum MaxRGBFloat
= 65535.0f;
45 enum MaxRGBDouble
= 65535.0;
46 /* TODO: Scale functions */
47 alias Quantum
= ushort;
49 else static if (QuenatumDepth
== 32)
51 enum MaxColormapSize
= 65536U;
52 enum MaxRGB
= 4294967295U;
53 enum MaxRGBFloat
= 4294967295.0f;
54 enum MaxRGBDouble
= 4294967295.0;
55 /* MaxMap defines the maximum index value for algorithms which depend on
56 * lookup tables (e.g. colorspace transformations and normalizations).
57 * When MaxMap is less than MaxRGB it is necessary to downscale samples to
58 * fit the range of MaxMap. The number of bits which are effectively
59 * preserved depend on the size of MaxMap. MaxMap should be a multiple of
60 * 255 and no larger the MaxRGB. Note that tables can become quite large
61 * and as tables grow larger it may take more time to compute the table
62 * than to process the image. */
64 enum MaxMapDepth
= 16;
65 enum MaxMapFloat
= 65535.0f;
66 enum MaxMapDouble
= 65535.0;
68 static if (MaxMap
== 65535U)
70 /* TODO: Scale functions */
74 /* TODO: Scale functions */
80 static assert(false, "Specified value of QuantumDepth is not supported");
84 alias AlphaType
= int;
92 alias ChannelType
= int;
96 RedChannel
, /* RGB Red channel */
97 CyanChannel
, /* CMYK Cyan channel */
98 GreenChannel
, /* RGB Green channel */
99 MagentaChannel
, /* CMYK Magenta channel */
100 BlueChannel
, /* RGB Blue channel */
101 YellowChannel
, /* CMYK Yellow channel */
102 OpacityChannel
, /* Opacity channel */
103 BlackChannel
, /* CMYK Black (K) channel */
104 MatteChannel
, /* Same as Opacity channel (deprecated) */
105 AllChannels
, /* Color channels */
106 GrayChannel
/* Color channels represent an intensity. */
109 /// ClassType enumeration specifies the image storage class.
110 alias ClassType
= int;
115 /// Image is composed of pixels which represent literal color values.
117 /// Image is composed of pixels which specify an index in a color palette.
122 + CompositeOperator is used to select the image composition algorithm used to
123 + compose a "composite image" with an "image".
125 + By default, each of the "composite image" pixels are replaced by the
126 + corresponding "image" tile pixel. Specify CompositeOperator to select a
127 + different algorithm.
129 + The image compositor requires a matte, or alpha channel in the image for
130 + some operations. This extra channel usually defines a mask which
131 + represents a sort of a cookie-cutter for the image. This is the case when
132 + matte is 255 (full coverage) for pixels inside the shape, zero outside, and
133 + between zero and 255 on the boundary. For certain operations, if "image"
134 + does not have a matte channel, it is initialized with `0` for any pixel
135 + matching in color to pixel location `(0, 0)`, otherwise 255 (to work
136 + properly borderWidth must be `0`).
138 alias CompositeOperator
= int;
145 UndefinedCompositeOp
= 0,
147 + The result is the union of the two image shapes with the "composite
148 + image" obscuring the "image" in the region of overlap.
152 + The result is a simply "composite image" cut by the shape of "image".
153 + None of the image data of "image" is included in the result.
157 + The resulting image is "composite image" with the shape of "image" cut
162 + The result is the same shape as "image", with "composite image"
163 + obscuring "image" where the image shapes overlap.
165 + Note that this differs from `OverCompositeOp` because the portion of
166 + "composite image" outside of "image"'s shape does not appear in the
171 + The result is the image data from both "composite image" and "image"
172 + that is outside the overlap region.
174 + The overlap region will be blank.
178 + The result is just the sum of image data.
180 + Output values are cropped to 255 (no overflow). This operation is
181 + independent of the matte channels.
185 + The result of `"composite image" - "image"`, with overflow cropped to
188 + The matte channel is ignored (set to 255, full coverate).
192 + The result of `"composite image" + "image"`, with overflow wrapping
197 + The result of `"composite image" - "image"`, with underflow wrapping
200 + The add and subtract operators can be used to perform reversible
205 + The result of `abs("composite image" - "image")`.
207 + This is useful for comparing two very similar images.
209 DifferenceCompositeOp
,
211 + The result image shaded by "composite image".
215 + The resulting image is "image" replaced with "composite image".
217 + Here the matte information is ignored.
221 + The resulting image is the red layer in "image" replaced with the red
222 + layer in the "composite image".
224 + The othe layers are copied untouched.
228 + The resulting image is the green layer in "image" replaced with the
229 + green layer in the "composite image".
231 + The othe layers are copied untouched.
233 CopyGreenCompositeOp
,
235 + The resulting image is the blue layer in "image" replaced with the blue
236 + layer in the "composite image".
238 + The othe layers are copied untouched.
242 + The resulting image is the matte layer in "image" replaced with the
243 + matte layer in the "composite image".
245 + The othe layers are copied untouched.
247 CopyOpacityCompositeOp
,
249 + Pixels in the region are set to Transparent.
255 + Modulate brightness in HSL space.
258 ThresholdCompositeOp
,
266 + Copy Hue channel (from HSL colorspace)
270 + Copy Saturation channel (from HSL colorspace)
274 + Copy Hue and Saturation channels (from HSL colorspace)
278 + Copy Brightness channel (from HSL colorspace)
281 /// [Not yet implemented]
283 /// [Not yet implemented]
286 + Copy the Cyan channel.
290 + Copy the Magenta channel.
292 CopyMagentaCompositeOp
,
294 + Copy the Yellow channel.
296 CopyYellowCompositeOp
,
298 + Copy the Black channel.
300 CopyBlackCompositeOp
,
302 HardLightCompositeOp
,
303 ExclusionCompositeOp
,
304 ColorDodgeCompositeOp
,
305 ColorBurnCompositeOp
,
306 SoftLightCompositeOp
,
307 LinearBurnCompositeOp
,
308 LinearDodgeCompositeOp
,
309 LinearLightCompositeOp
,
310 VividLightCompositeOp
,
316 + CompressionType is used to express the desired compression type when
319 + Be aware that most image types only support a sub-set of the available
320 + compression types. If the compression type specified is incompatible with
321 + the image, Magick will select a compression type compatible with the image
322 + type, which might be no compression at all.
324 alias CompressionType
= int;
329 UndefinedCompression
,
333 + BZip (Burrows-Wheeler block-sorting text compression algorithm and
334 + Huffman coding) as used by bzip2 utilities.
337 /// CCITT Group 3 FAX compression
339 /// CCITT Group 4 FAX compression (used only for TIFF)
343 /// Lossless JPEG compression
344 LosslessJPEGCompression
,
345 /// Lempel-Ziv-Welch (LZW) compression (caution: patented by Unisys)
347 /// Run-Length encoded (RLE) compression
349 /// Lempel-Ziv compression (LZ77) as used in PKZIP and GNU gzip.
351 /// LZMA - Lempel-Ziv-Markov chain algorithm
353 /// JPEG 2000 - ISO/IEC std 15444-1
355 /// JBIG v1 - ISO/IEC std 11544 / ITU-T rec T.82
357 /// JBIG v2 - ISO/IEC std 14492 / ITU-T rec T.88
359 /// Facebook's Zstandard/Zstd
365 alias DisposeType
= int;
374 alias EndianType
= int;
378 LSBEndian
, /* "little" endian */
379 MSDEndian
, /* "big" endian */
380 NativeEndian
/* native endian */
383 alias FilterTypes
= int;
405 + GravityType specifies positioning of an object (e.g. text, image) within a
406 + bouding region (e.g. an image).
408 + Gravity provides a convenient way to locate objects irrespective of the
409 + size of the bounding region, in other words, you don't need to provide
410 + absolute coordinates in order to position an object. A common default for
411 + gravity is NorthWestGravity.
413 alias GravityType
= int;
417 /// Don't use gravity.
419 /// Position object at top-left of region.
421 /// Position object at top-center of region.
423 /// Position object at top-right of region.
425 /// Position object at left-center of region.
427 /// Position object at center of region.
429 /// Position object at right-center of region.
431 /// Position object at left-bottom of region.
433 /// Position object at bottom-center of region.
435 /// Position object at bottom-right of region.
441 + ImageType indicates the type classification of the image.
443 alias ImageType
= int;
449 /// Monochrome image.
453 /// Grayscale image with opacity
455 /// Indexed color (palette) image.
457 /// Indexed color (palette) image with opacity.
461 /// Truecolor image with opacity.
463 /// Cyan/Yellow/Magenta/Black (CYMK) image
465 /// Cyan/Yellow/Magenta/Black (CYMK) image with opacity.
466 ColorSeparationMatteType
,
471 + InterlaceType specifies the ordering of the red, green, and blue pixel
472 + information in the image.
474 + Interlacing is usually used to make image information available to the user
475 + faster by taking advantage of the space vs. time tradeoff. For example,
476 + interlacing allows images on the Web to be recognizable sooner and
477 + satellite images to accumulate/render with image resolution increasing over
480 + Use `LineInterlace` or `PlaneInterlace` to create an interlace GIF or
481 + progressive JPEG image.
483 alias InterlaceType
= int;
492 + Don't interlace image (RGBRGBRGBRGBRGBRGB...)
496 + Use scanline interlacing (RRR...GGG...BBB...RRR...GGG...BBB)
500 + Use plane interlacing (RRRRRR...GGGGGG...BBBBBB...)
504 + Similar to plane interlacing except that the different planes are
505 + saved to individual files (e.g. image.R, image.G, and image.B)
511 + NoiseType is used as an argument to select the type of noise to be added to
514 alias NoiseType
= int;
520 MultiplicativeGaussianNoise
,
529 + OrientationType specifies the orientation of the image.
531 + Useful for when the image is produced via a different ordinate system, the
532 + camera was turned on its side, or the page was scanned sideways.
534 alias OrientationType
= int;
538 /// Scanline dir: Unknown; Frame dir: Unknown
539 UndefinedOrientation
,
540 /// Scanline dir: Left to Right; Frame dir: Top to Bottom
542 /// Scanline dir: Right to Left; Frame dir: Top to Bottom
544 /// Scanline dir: Right to Left; Frame dir: Bottom to Top
545 BottomRightOrientation
,
546 /// Scanline dir: Left to Right; Frame dir: Bottom to Top
547 BottomLeftOrientation
,
548 /// Scanline dir: Top to Bottom; Frame dir: Left to Right
550 /// Scanline dir: Top to Bottom; Frame dir: Right to Left
552 /// Scanline dir: Bottom to Top; Frame dir: Right to Left
553 RightBottomOrientation
,
554 /// Scanline dir: Bottom to Top; Frame dir: Left to Right
555 LeftBottomOrientation
559 + Rendering intent is a concept defined by ICC Spec ICC.1:1998-09, "File
560 + Format for Color Profiles".
562 + GraphicsMagick uses RenderingIntent in order to support ICC Color Profiles.
564 + From the specification:
565 + "Rendering intent specifies the style of reproduction to be used during the
566 + evaluation of this profile in a sequence of profiles. It applies
567 + specifically to that profile in the sequence and not to th entire sequence.
568 + Typically, the user or application will set the rendering intent
569 + dynamically at runtime or embedding time."
571 alias RenderingIntent
= int;
580 + A rendering intent that specifies the saturation of the pixels in the
581 + image is preserved perhaps at the expense of accuracy in hue and
586 + A rendering intent that specifies the full gamut of the image is
587 + compressed or expanded to fill the gamut of the destination device.
589 + Gray balance is preserved but colorimetric accuracy might not be
594 + Absolute colorimetric.
598 + Relative colorimetric
604 + By default, Magick defines resolution pixels per inch.
606 + ResolutionType provides a means to adjust this.
608 alias ResolutionType
= int;
615 + Density specifications are specified in units of pixels per inch
618 PixelsPerInchResolution
,
620 + Density specifications are specified in units of pixels per centimeter
623 PixelsPerCentimeterResolution
628 + --------------------------------------------------------------------------
629 + Structure Definitions
630 + --------------------------------------------------------------------------
652 + The ChromaticityInfo structure is used to represent chromaticity
653 + (colorspace primary coordinates in xy space) values for images in Magick.
655 struct ChromaticityInfo
657 /// Chromaticity red primary point (e.g. x=0.64, y=0.33)
658 PrimaryInfo red_primary
;
659 /// Chromaticity green primary point (e.g. x=3, y=0.6)
660 PrimaryInfo green_primary
;
661 /// Chromaticity blue primary point (e.g. x=0.15, y=0.06)
662 PrimaryInfo blue_primary
;
663 /// Chromaticity white point (e.g. x=0.3127, y=0.329)
664 PrimaryInfo white_point
;
671 // enum MAGICK_PIXELS_RGBA = 1;
678 /* BGRA (as used by Microsoft Windows DIB) */
679 // enum MAGICK_PIXELS_BGRA = 1;
687 struct DoublePixelPacket
695 struct FloatPixelPacket
704 + ErrorInfo is used to record statistical difference (error) information
705 + based on computed Euclidean distance in RGB space.
709 /// Average error per pixel (absolute range).
710 double mean_error_per_pixel
;
711 /// Average error per pixel (normalized to 1.0).
712 double normalized_mean_error
;
713 /// Maximum error encountered (normalized to 1.0).
714 double normalized_maximum_error
;
718 + The RectangleInfo structure is used to represent positioning information
727 /// Rectangle horizontal offset
729 /// Rectangle vertical offset.
736 struct _ThreadViewSet
;
737 struct _ImageAttribute
;
740 struct _SemaphoreInfo
;
743 + The image structure represents a Magick image.
745 + It is initially allocated by AllocateImage() and deallocated by
746 + DestroyImage(). The functions ReadImage(), ReadImages(), BlobToImage,
747 + and CreateImage() return a new Image. Use CloneImage() to copy an image.
748 + An image consists of a structure containing image attributes as well as the
754 + Image storage class.
756 + If DirectClass then the image packets contain valid RGB or CMYK colors.
757 + If PseudoClass then the image has a colormap referenced by pixel's
760 ClassType storage_class
;
762 + Image pixel interpretation.
764 + If the colorspace is RGB the pixels are red, green, blue. If matte is
765 + true, then red, green, blue, and index. If it is CMYK, the pixels are
766 + cyan, yellow, magenta, black. Otherwise, the colorspace is ignored.
768 ColorspaceType colorspace
;
770 + Image compression type.
772 + The default compression type of the specified image file.
774 CompressionType compression
;
776 + Should the image be dithered.
780 + If non-zero, then the index member of pixels represents the alpha
793 + The desired number of colors.
795 + Used by QuantizeImage().
801 + Number of encoding bits per sample. Usually 8 or 16, but sometimes
806 + PseudoColor palette array.
808 PixelPacket
* colormap
;
810 + Image background color.
812 PixelPacket background_color
;
814 + Image border color.
816 PixelPacket border_color
;
818 + Image matte (transparent) color.
820 PixelPacket matte_color
;
822 ChromaticityInfo chromaticity
;
823 OrientationType orientation
;
824 RenderingIntent rendering_intent
;
825 ResolutionType units
;
833 RectangleInfo tile_info
;
837 InterlaceType interlace
;
840 CompositeOperator compose
;
845 c_ulong total_colors
;
850 char[MaxTextExtent
] filename
;
851 char[MaxTextExtent
] magick_filename
;
852 char[MaxTextExtent
] magick
;
853 c_ulong magick_columns
;
855 ExceptionInfo exception
;
870 _ThreadViewSet
* default_views
;
871 _ImageAttribute
* attributes
;
872 _Ascii85Info
* ascii85
;
875 c_long reference_count
;
877 _SemaphoreInfo
* semaphore
;
888 + Image compresion type.
890 + The default is the compression type of the specified image file.
892 CompressionType compression
;
894 + Remove file "filename" once it has been read.
896 MagickBool temporary
;
898 + Join images into a single multi-image file.
902 + Control antialiasing of rendered Postscript and Postscript or TrueType
903 + fonts. Enabled by default.
905 MagickBool antialias
;
907 + Subimage of an image sequence.
911 + Number of images relative to the base image.
915 + Image depth (8 or 16).
919 + Width and height of a raw image (an image which does not support width
920 + and height information).
922 + Size may also be used to affect the image size read from a
923 + multi-resolution format (e.g. Photo CD, JBIG, or JPEG).
931 + Equivalent size of Postscript page.
935 + The type of interlacing scheme (default NoInterlace).
937 + This option is used to specify the type of interlacing scheme for raw
938 + image formats such as RGB or YUV. NoInterlace means to not interlace,
939 + LineInterlace uses scanline interlacing, and PlaneInterlace uses plane
940 + interlacing. PartitionInterlace is like PlaneInterlace except the
941 + different planes are saved to individual files (e.g. image.R, image.G,
942 + and image.B). Use LineInterlace or PlaneInterlace to create an
943 + interlaced GIF or progressive JPEG image.
945 InterlaceType interlace
;
947 + Select MSB/LSB endian output for TIFF format.
951 + Units of image resolution.
953 ResolutionType units
;
955 + JPEG/MIFF/PNG compression level (default 75).
959 + JPEG, MPEG, and YUV chroma downsample factor.
961 char* sampling_factor
;
963 + X11 display to obtain fonts from, or to capture image from.
967 + Text rendering font.
969 + If the font is a fully qualified X server font name, the font is
970 + obtained from an X server. To use a TrueType font, precede the
971 + TrueType filename with an `@`. Otherwise, specify a Postscript font
972 + name (e.g. "helvetica").
976 + Image filename to use as background texture.
980 + Vertical and horizontal resolution in pixels of the image.
982 + This option specifies an image density when decoding a Postscript or
983 + Portable Document page. Often used with page.
987 + Text rendering font point size.
991 + Colors within this distance are considered equal.
993 + A number of algorithms seach for a target color. By default the color
994 + must be exact. Use this option to match colors that are close to the
995 + target color in RGB space.
999 + Stroke or fill color while drawing.
1003 + Image background color
1005 PixelPacket background_color
;
1007 + Image border color.
1009 PixelPacket border_color
;
1011 + Image matte (transparent) color.
1013 PixelPacket matte_color
;
1015 + Apply Floyd/Steinberg error diffusion to the image.
1017 + The basic strategy of dithering is to trade intensity resolution for
1018 + spacial resolution by averaging the intesities of several neighboring
1019 + pixels. Images which suffer from severe contouring when reducing
1020 + colors can be improved with this option. The colors or monochrome
1021 + option must be set for this option to take effect.
1025 + Transform the image to black and white.
1027 MagickBool monochrome
;
1029 + Show progress indication.
1031 MagickBool progress
;
1033 + Image pixel interpretation.
1035 + If the colorspace is RGB the pixels are red, green, blue. If `matte`
1036 + is true, then red, green, blue, and index. If it is CMYK, the pixels
1037 + are cyan, yellow, magenta, black. Otherwise the colorspace is ignored.
1039 ColorspaceType colorspace
;
1041 + Desired image type (used while reading or writing).
1045 + X11 Window group ID
1049 + Print detailed information about the image if True.
1053 + FlashPix viewing parameters.
1057 + Password used to decrypt file.
1061 + User-specified data to pass to coder.
1065 + stdio stream to read image from or write image to.
1067 + If set, Magick will read from or write to the stream rather than
1068 + opening a file. Used by ReadImage() and WriteImage(). The stream is
1069 + closed when the operation completes.
1073 + Image encoding format (e.g. "GIF").
1075 char[MaxTextExtent
] magick
;
1077 + Image file name to read or write.
1079 char[MaxTextExtent
] filename
;
1081 /* XXX: haven't done private members yet, wonder if they're needed to
1087 + --------------------------------------------------------------------------
1089 + --------------------------------------------------------------------------
1094 + AccessDefinition() searches the definitions for an entry matching the
1095 + specified magick and key.
1097 + NULL is returned if no matching entry is found.
1100 + image_info = The image info.
1101 + magick = Format ID. This is usually the same as the coder name.
1102 + key = The key to search for.
1104 const(char)* AccessDefinition(const ImageInfo
* image_info
, const char* magick
,
1108 + AddDefinition() adds a key/value definition to the current map of
1109 + definitions in ImageInfo.
1111 + Definitions may be used by coders/decoders that read and write images.
1114 + image_info = The image info.
1115 + magick = Format/classification identifier.
1116 + key = Subidentifier within format/classification.
1117 + value = Definition value
1118 + exception = Errors result in updates to this structure.
1120 MagickPassFail
AddDefinition(ImageInfo
* image_info
, const char* magick
,
1121 const char* key
, const char* value
,
1122 ExceptionInfo
* exception
);
1125 + CloneImageInfo() copies an image and returns the copy as a new image
1128 + If the specified `columns and `rows` is `0`, an exact copy of the image is
1129 + returned, otherwise, the pixel data is undefined and must be initialzed
1130 + with the SetImagePixels() and SyncImagePixels() methods. On failure, a
1131 + NULL image is returned and `exception` describes the reason for failure.
1135 + columns = The number of columns in the cloned image.
1136 + rows = The numbe of rows in the cloned image.
1137 + orphan = With a value other than 0, the cloned image is an orphan. An
1138 + orphan is a stand-alone image that is not associated with an image list.
1139 + In effect, the next and previous members of the cloned image is set to
1141 + exception = Return any errors or warnings to this structure.
1143 Image
* CloneImage(const Image
* image
, const c_ulong columns
,
1144 const c_ulong rows
, const uint orphan
,
1145 ExceptionInfo
* exception
);
1148 + CloneImageInfo() makes a copy of the given `ImageInfo` structure.
1150 + If NULL is specified, a new image info structure is created an initialized
1151 + to default values.
1154 + image_info = The image info
1156 ImageInfo
* CloneImageInfo(const ImageInfo
* image_info
);
1159 + DestroyImage() dereferences an image, deallocating memory associated with
1160 + the image if the reference count becomes zero.
1162 + There is no effect if the image pointer is null.
1164 + In the interest of avoiding dangling pointers or memory leaks, the image
1165 + previous and next pointers should be null when this function is called, and
1166 + no othe image should refer to it. In the future this may be enforced.
1169 + image = The image.
1171 void DestroyImage(Image
* image
);
1174 + DestroyImageInfo() deallocates memory associated with an `ImageInfo`
1178 + image_info = The image info.
1180 void DestroyImageInfo(ImageInfo
* image_info
);