úΙjNÿ—      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl m n o p q r s t u v w x y z { | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž   ‘ ’ “ ” • – (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone$*9:;<=DRTEÿ'Approach to be used near the borders during various transformations. Whenever a function needs information not only about a pixel of interest, but also about it's neighbours, it will go out of bounds around the image edges, hence is this set of approaches that can be used in such situtation.Fill in a constant pixel. ( outside | Image | outside (" 0) : 0 0 0 0 | 1 2 3 4 | 0 0 0 0 2Wrap around from the opposite border of the image. ' outside | Image | outside # : 1 2 3 4 | 1 2 3 4 | 1 2 3 4  Replicate the pixel at the edge. ' outside | Image | outside # : 1 1 1 1 | 1 2 3 4 | 4 4 4 4 Mirror like reflection. ' outside | Image | outside  : 4 3 2 1 | 1 2 3 4 | 4 3 2 1 BAlso mirror like reflection, but without repeating the edge pixel. ' outside | Image | outside  : 1 4 3 2 | 1 2 3 4 | 3 2 1 4 7Allows for changing an underlying image representation.9Exchange the underlying array representation of an image.‘Array representation that is actually has real data stored in memory, hence allowing for image indexing, forcing pixels into computed state etc.Get a pixel at i-th and j -th location.Ylet grad_gray = makeImage (200, 200) (\(i, j) -> PixelY $ fromIntegral (i*j)) / (200*200)8index grad_gray (20, 30) == PixelY ((20*30) / (200*200))True+Make sure that an image is fully evaluated. 1Fold an image from the left in a row major order.!2Fold an image from the right in a row major order."TCreate an Image by supplying it's dimensions and a monadic pixel generating action.#Monading mapping over an image.$4Monading mapping over an image. Result is discarded.%Monadic folding.&%Monadic folding. Result is discarded.'"Get dimensions of a mutable image.(!Yield a mutable copy of an image.)$Yield an immutable copy of an image.*NCreate a mutable image with given dimensions. Pixels are likely uninitialized.+$Yield the pixel at a given location., Set a pixel at a given location.-Swap pixels at given locations.0NCreate an Image by supplying it's dimensions and a pixel generating function.1SCreate a singleton image, required for various operations on images with a scalar.2Retrieves a pixel at (0, 0) index. Useful together with =*, when arbitrary initial pixel is needed.3Map a function over a an image.48Map an index aware function over each pixel in an image.5Zip two images with a function6+Zip two images with an index aware function7Traverse an image8Traverse two images.9Transpose an image:#Backwards permutation of an image. ;mConstruct an image from a nested rectangular shaped list of pixels. Length of an outer list will constitute m* rows, while the length of inner lists - nJ columns. All of the inner lists must be the same length and greater than 0.<IPerform matrix multiplication on two images. Inner dimensions must agree.=!Undirected reduction of an image.>ÑPixelwise equality function of two images. Images are considered distinct if either images' dimensions or at least one pair of corresponding pixels are not the same. Used in defining an in instance for the — typeclass.A,Base array like representation for an image.B9Required array specific constraints for an array element.C Underlying image representation.DGet dimensions of an image.)frog <- readImageRGB VU "images/frog.jpg"frog+<Image VectorUnboxed RGB (Double): 200x320> dims frog (200,320)E§A class with a set of convenient functions that allow for changing precision of channels within pixels, while scaling the values to keep them in an appropriate range.2let rgb = PixelRGB 0.0 0.5 1.0 :: Pixel RGB Double toWord8 rgb<RGB:(0|128|255)>M)A color space that supports transparency.N4An corresponding opaque version of this color space.O-Get an alpha channel of a transparant pixel. P(Add an alpha channel of an opaque pixel. 1 addAlpha 0 (PixelHSI 1 2 3) == PixelHSIA 1 2 3 0QLConvert a transparent pixel to an opaque one by dropping the alpha channel. 0 dropAlpha (PixelRGBA 1 2 3 4) == PixelRGB 1 2 3R(Get a corresponding opaque channel type.SÍThis class has all included color spaces installed into it and is also intended for implementing any other possible custom color spaces. Every instance of this class automatically installs an associated U into ˜, ™, š, ›, œ and H, which in turn make it possible to be used by the rest of the library.T¢Representation of a pixel, such that it can be an element of any Array. Which is usally a tuple of channels or a channel itself for single channel color spaces.U=A concrete Pixel representation for a particular color space.VGConstrut a pixel by replicating a same value among all of the channels.WmConvert a Pixel to a representation suitable for storage as an unboxed element, usually a tuple of channels.X6Convert from an elemnt representation back to a Pixel.YRetrieve Pixel's channel valueZ7Map a channel aware function over all Pixel's channels.[)Map a function over all Pixel's channels.\ Function application to a Pixel.]A pixel eqiuvalent of ž.^.Get a pure colour representation of a channel._K function that allows restricting representation type of the source image.`Border handling function. If (i, j) location is within bounds, then supplied lookup function will be used, otherwise it will be handled according to a supplied border strategy.aOImage indexing function that returns a default pixel if index is out of bounds.bbImage indexing function that uses a special border resolutions strategy for out of bounds pixels.c%Image indexing function that returns Ÿ if index is out of bounds,   px otherwise.rDChanging to the same array representation as before is disabled and / will behave simply as an identitity function.` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_New representation of an image. Source image.`Border handling strategy.Image dimensionsImage's indexing function.(i, j) location of a pixel lookup.abcdefghijklmnopqrQ!()+#*$- ,%&"'./74391=5>8:60;<2?@ACBDEJFGHIKLMNROPQSUTVWXYZ[\]^_`abcQSTUVWXYZ[\]^MNOPQREFGHIJKLABCD./0123456789:;<=>?@ !"#$%&'()*+,-_abc` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS TUVWXYZ[\]^_`abcdefghijklmnopqr (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone$tBilinear interpolation method.v&Nearest Neighbor interpolation method.x+Implementation for an interpolation method.yCConstruct a new pixel by using information from neighboring pixels.tuvwxy¡¢tuvwxytuvwxy¡¢ (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone${.Upsample an image by a positive factor. Every |0Downsample an image by discarding every odd row.}3Downsample an image by discarding every odd column.~;Downsample an image by discarding every odd row and column.VUpsample an image by inserting a row of back pixels after each row of a source image.€\Upsample an image by inserting a column of back pixels after each column of a source image.pUpsample an image by inserting a row and a column of back pixels after each row and a column of a source image.‚_Concatenate two images together into one. Both input images must have the same number of rows.ƒbConcatenate two images together into one. Both input images must have the same number of columns.„2Shift an image towards its bottom right corner by (delatM, deltaN)B rows and columns, while specifying a border resolution strategy.)frog <- readImageRGB VU "images/frog.jpg"KwriteImage "images/frog_translate_wrap.jpg" $ translate Wrap (50, 100) frogKwriteImage "images/frog_translate_edge.jpg" $ translate Edge (50, 100) frog images/frog.jpg  images/frog_translate_wrap.jpg images/frog_translate_edge.jpg…«Change the size of an image. Pixel values and positions will not change, except the ones outside the border, which are handled according to supplied resolution strategy. images/haskell_40.pngvFor example, it can be used to make a tile from the image above, or simply scale the canvas and place it in a middle:-logo <- readImageRGBA VU "images/logo_40.png"5let incBy (fm, fn) = (rows logo * fm, cols logo * fn)HwriteImage "images/logo_tile.png" $ canvasSize Wrap (incBy (6, 10)) logoqwriteImage "images/logo_center.png" $ translate (Fill 0) (incBy (2, 3)) $ canvasSize (Fill 0) (incBy (5, 7)) logo images/logo_tile.png images/logo_center.png†5Crop an image, i.e. retrieves a sub-image image with m rows and n columns. Make sure (i + m, j + n)Y is not greater than dimensions of a source image, otherwise it will result in an error.‡cPlace one image on top of a source image, starting at a particular location within a source image.ˆFlip an image vertically.)frog <- readImageRGB VU "images/frog.jpg"/writeImage "images/frog_flipV.jpg" $ flipV frog images/frog.jpg images/frog_flipV.jpg‰Flip an image horizontally.)frog <- readImageRGB VU "images/frog.jpg"/writeImage "images/frog_flipH.jpg" $ flipH frog images/frog.jpg images/frog_flipH.jpgŠ!Rotate an image clockwise by 90°.)frog <- readImageRGB VU "images/frog.jpg"5writeImage "images/frog_rotate90.jpg" $ rotate90 frog images/frog.jpg images/frog_rotate90.jpg‹Rotate an image by 180°.)frog <- readImageRGB VU "images/frog.jpg"7writeImage "images/frog_rotate180.jpg" $ rotate180 frog images/frog.jpg images/frog_rotate180.jpgŒ"Rotate an image clockwise by 270°.)frog <- readImageRGB VU "images/frog.jpg"7writeImage "images/frog_rotate270.jpg" $ rotate270 frog images/frog.jpg images/frog_rotate270.jpg3Rotate an image clockwise by an angle ˜ in radians.*frog <- readImageRGBA VU "images/frog.jpg"PwriteImage "images/frog_rotate330.png" $ rotate Bilinear (Fill 0) (11*pi/6) frog images/frog.jpg images/frog_rotate330.pngŽ.Resize an image using an interpolation method.)frog <- readImageRGB VU "images/frog.jpg"JwriteImage "images/frog_resize.jpg" $ resize Bilinear Edge (100, 640) frog images/frog_resize.jpg_Scale an image. Same as resize, except scaling factors are supplied instead of new dimensions.  scale t  (0.5, 2) frog == resize t  (100, 640) frog£Put an angle into  [0, 2*pi) range.€ Make sure  sin' pi == 0 instead of  sin pi == 1.2246467991473532e-16¥ Make sure cos' (pi/2) == 0 instead of #cos (pi/2) == 6.123233995736766e-17 and cos' (3*pi/2) == 0 instead of 'cos (3*pi/2) == -1.8369701987210297e-16z{|}~€‚ƒ„Border resolution strategy4Number of rows and columns image will be shifted by.…Border resolution strategyNew dimensions of the image Source image†(i, j)+ starting index from within a source image.(m, n) dimensions of a new image. Source image.‡(i, j)+ starting index from within a source image..Image to be positioned above the source image. Source image.Ј‰Š‹ŒInterpolation method to be usedBorder handling strategyAngle in radians Source image Rotated imageŽ/Interpolation method to be used during scaling.Border handling strategyDimensions of a result image. Source image. Result image./Interpolation method to be used during scaling.Border handling strategyPositive scaling factors. Source image.£€¥z{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽz{|}~€‚ƒ„…†‡Ј‰Š‹ŒŽ£€¥(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNonePConvolution of an image using a kernel. Border resolution technique is required.Example using  ,https://en.wikipedia.org/wiki/Sobel_operatorSobel operator:'frog <- readImageY RP "images/frog.jpg"Olet frogX = convolve Edge (fromLists [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) frogOlet frogY = convolve Edge (fromLists [[-1,-2,-1], [ 0, 0, 0], [ 1, 2, 1]]) frog7displayImage $ normalize $ sqrt (frogX ^ 2 + frogY ^ 2) images/frogY.jpg images/frog_sobel.jpg‘KConvolve image's rows with a vector kernel represented by a list of pixels.’NConvolve image's columns with a vector kernel represented by a list of pixels.§%Approach to be used near the borders. Kernel image. Source image.‘’‘’§‘’(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone$“This function magnifies an image by a positive factor and draws a grid around the original pixels. It is here simply as useful inspection tool.)frog <- readImageRGB VU "images/frog.jpg"SwriteImage "images/frog_eye_grid.png" $ pixelGrid 10 $ crop (51, 112) (20, 20) frog images/frog.jpg images/frog_eye_grid.png“Magnification factor. Source image.&tuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“&|}~z€{‚ƒ„…†‡ˆ‰Š‹ŒŽxyvwtu‘’““(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableSafe 9:;<=DR ”*Image formats that can be written to file.•Encode an image to š.–)Image formats that can be read from file.—Decode an image from š.˜Image file format. Helps in guessing image format using a file extension, as well as supplying format specific options during saving an image.™@Options that can be used during writing an image in this format.š-Default file extension for this image format.›'Known extensions for this image format.œReturns © if a file extension (ex. ".png") corresponds to this format.ª0Used during converting pixels between libraries. ”•–—˜™š›œª« ”•–—˜™š›œª«”•–—˜™š›œª«(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DRConversion to £- from another color space with Alpha channel.žConvert to an £ pixel.ŸConvert to an £ image. Conversion to š color space.¡Convert to an š pixel.¢Convert to an š image.£%YCbCr color space with Alpha channel.€$Luma component (commonly denoted as Y')¥ Blue difference chroma componentŠRed difference chroma component§Alpha component.šNColor space is used to encode RGB information and is used in JPEG compression.©$Luma component (commonly denoted as Y')ª Blue difference chroma component«Red difference chroma componentžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶U­¬žŸ ¡¢£€¥Š§š©ª« žŸ ¡¢£€¥Š§š©ª«®¯°±²Ž³¬¶µ­(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DR¬Conversion to ²- from another color space with Alpha channel.­Convert to an ² pixel.®Convert to an ² image.¯Conversion to · color space.°Convert to an · pixel.±Convert to an · image.²3Red, Green and Blue color space with Alpha channel.· Red, Green and Blue color space.¬­®¯°±²³Žµ¶·ž¹º·ž¹º»ŒœŸ¿ÀÁUž·¬­®¯°±²³Žµ¶·ž¹º ¬­®¯°±²³Žµ¶·ž¹º¹º»Œœ¿Ÿ·ÁÀž(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DR »?Conversion to Luma from another color space with Alpha channel.Œ)Convert a pixel to Luma pixel with Alpha.œ*Convert an image to Luma image with Alpha.ŸConversion to Luma color space.¿Convert a pixel to Luma pixel.ÀConvert an image to Luma image.ÁLuma with Alpha channel.ÂLumaà Alpha channelÄ/Luma or brightness, that is usually denoted as Y'.»ŒœŸ¿ÀÁÂÃÄÅÂÃÄÅÆÇÈÉÊËÌÍUûŒœŸ¿ÀÁÂÃÄÅ »ŒœŸ¿ÀÁÂÃÄÅÄÅÆÇÈÉËÊÂÍÌÃ(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DRÆConversion to Ì- from another color space with Alpha channel.ÇConvert to an Ì pixel.ÈConvert to an Ì image.ÉConversion to Ñ color space.ÊConvert to an Ñ pixel.ËConvert to an Ñ image.Ì=Hue, Saturation and Intensity color space with Alpha channel.ÍHueÎ SaturationÏ IntensityÐAlphaÑ*Hue, Saturation and Intensity color space.ÒHueÓ Saturation Ô IntensityÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÎÏÐÑÒÓÔÕÖרUÏÎÆÇÈÉÊËÌÍÎÏÐÑÒÓÔ ÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÐÑÒÓÔÖÕÎØ×Ï(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DRTÕÿThis is a signgle channel colorspace, that is designed to hold any channel from any other colorspace, hence it is not convertible to and from, but rather is here to allow separation of channels from other multichannel colorspaces. If you are looking for a true grayscale colorspace  should be used instead.×-Separate an image into a list of images with Õ8 pixels containing every channel from the source image.&frog <- readImageRGB "images/frog.jpg"9let [frog_red, frog_green, frog_blue] = toGrayImages frog4writeImage "images/frog_red.png" $ toImageY frog_red8writeImage "images/frog_green.jpg" $ toImageY frog_green6writeImage "images/frog_blue.jpg" $ toImageY frog_blue images/frog_red.jpg  images/frog_green.jpg images/frog_blue.jpgØCombine a list of images with ÕY pixels into an image of any color space, by supplying an order of color space channels.(For example here is a frog with swapped BlueRGB and GreenRGB channels.owriteImage "images/frog_rbg.jpg" $ fromGrayImages [frog_red, frog_green, frog_blue] [RedRGB, BlueRGB, GreenRGB] images/frog.jpg images/frog_rbg.jpg¶It is worth noting though, despite that separating image channels can be sometimes pretty useful, the same effect as above can be achieved in a much simpler and more efficient way: . map ((PixelRGB r g b) -> PixelRGB r b g) frog ÕÖÙרÚÛÜÝUÙÕÖרÕÖרÚÛÝÜÙ(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone ÙPConstrcut a complex pixel from two pixels representing real and imaginary parts.  PixelRGB 4 8 6 Ù PixelRGB 7 1 1 == PixelRGB (4  7) (8  1) (6  1)Ú*Extracts the real part of a complex pixel.Û/Extracts the imaginary part of a complex pixel.ÜBForm a complex pixel from polar components of magnitude and phase.ÝÝ t9 is a complex pixel with magnitude 1 and phase t (modulo 2*Þ).Þ The function Þ• takes a complex pixel and returns a (magnitude, phase) pair of pixels in canonical form: the magnitude is nonnegative, and the phase in the range (-Þ, Þ]1; if the magnitude is zero, then so is the phase.ß-The nonnegative magnitude of a complex pixel.à+The phase of a complex pixel, in the range (-Þ, Þ]2. If the magnitude is zero, then so is the phase.á!The conjugate of a complex pixel. ÙÚÛÜÝÞßàá ÙÚÛÜÝÞßàá ÙÚÛÜÝÞßàáÙ6(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone*:TâFast Fourier TransformãInverse Fast Fourier Transformß Check if à is a power of two.áICompute the DFT of a matrix. Array dimensions must be powers of two else â. ãäåâãæßáçèâãßãäåâãæßáçè(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone: äPConstruct a complex image from two images representing real and imaginary parts.)frog <- readImageRGB VU "images/frog.jpg" frog !+! 03<Image VectorUnboxed RGB (Complex Double): 200x320> frog !+! frog3<Image VectorUnboxed RGB (Complex Double): 200x320>å*Extracts the real part of a complex image.æ/Extracts the imaginary part of a complex image.çBForm a complex image from polar components of magnitude and phase.èè t9 is a complex image with magnitude 1 and phase t (modulo 2*Þ).é The function é• takes a complex image and returns a (magnitude, phase) pair of images in canonical form: the magnitude is nonnegative, and the phase in the range (-Þ, Þ]1; if the magnitude is zero, then so is the phase.ê-The nonnegative magnitude of a complex image.ë+The phase of a complex image, in the range (-Þ, Þ]2. If the magnitude is zero, then so is the phase.ì!The conjugate of a complex image.í>Make a filter by using a function that works around a regular (x, y) coordinate system.î&Apply a filter to an image created by í. äåæçèéêëìíDimensions of the filter. Both m and n have to be powers of 2, i.e. m == 2^k, where k is some integer.î Source image.Filter. âãäåæçèéêëìíî äåæçèéêëìíîâã äåæçèéêëìíîä6(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DRïConversion to õ- from another color space with Alpha channel.ð Convert to a õ pixel.ñ Convert to a õ image.òConversion to û color space.ó Convert to a û pixel.ô Convert to a û image.õ?Cyan, Magenta, Yellow and Black color space with Alpha channel.öCyan÷MagentaøYellowù Key (Black)úAlpha û,Cyan, Magenta, Yellow and Black color space.üCyanýMagentaþYellowÿ Key (Black)ïðñòóôõö÷øùúûüýþÿéêëìíîïðñòóUêéïðñòóôõö÷øùúûüýþÿ ïðñòóôõö÷øùúûüýþÿëìíîïñðéóòê(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 09:;DR1Under the hood, Binary pixels are represented as  that can only take values of 0 or 1.JThis is a Binary colorspace, pixel's of which can be created using these  constructors: Represents value 1 or ©7. It's a foreground pixel and is displayed in black.Represents value 0 or ô7. It's a background pixel and is displayed in white.tNote, that values are inverted before writing to or reading from file, since grayscale images represent black as a 0 value and white as 1 on a [0,1] scale.OBinary pixels also behave as binary numbers with a size of 1-bit, for instance:!on + on -- equivalent to: 1 .|. 1 <Binary:(1)>1(on + on) * off -- equivalent to: (1 .|. 1) .&. 0 <Binary:(0)>(on + on) - on <Binary:(0)>Represents value © or 1? in binary. Often also called a foreground pixel of an object.Represents value ô or 02 in binary. Often also called a background pixel. Convert a õ to a PixelBin pixel.isOn (fromBool True)TrueTest if Pixel's value is .Test if Pixel's value is .'Invert value of a pixel. Equivalent of ö for Bool's.÷øùúûüý ÷ø ÷øúûýüù(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone :<=DRþUnboxing of a U.ÿUnboxing of a .þ   ÿ   þ   ÿ(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone$*9:;<=DORTUnboxed   representation. (Convert an image to a flattened Unboxed   . It is a O(1) opeartion.KtoUnboxedVector $ makeImage (3, 2) (\(i, j) -> PixelY $ fromIntegral (i+j))XfromList [<Luma:(0.0)>,<Luma:(1.0)>,<Luma:(1.0)>,<Luma:(2.0)>,<Luma:(2.0)>,<Luma:(3.0)>] 'Construct a two dimensional image with m rows and n columns from a flat Unboxed   of length k . It is a O(1) opeartion. Make sure that  m * n = k.UfromUnboxedVector (200, 300) $ generate 60000 (\i -> PixelY $ fromIntegral i / 60000)#<Image VectorUnboxed Luma: 200x300> images/grad_fromVector.png %2D to a flat vector index conversion.Note': There is an implicit assumption that j < n #Flat vector to 2D index conversion.    n columns(i, j) row, column indexFlat vector index n columnsFlat vector index(i, j) row, column index C           (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone$*9:;<=DRT Repa U=nboxed Array representation, which is computed sequentially. Repa U;nboxed Array representation, which is computed in parallel.šCombine two arrays, element-wise, with index aware operator. If the extent of the two array arguments differ, then the resulting array's extent is their intersection.7Create a sequential image from a 2D Repa delayed array.5Create a parallel image from a 2D Repa delayed array.0Retrieve an underlying Repa array from an image.(O(1) - Changes to Vector representation.(O(1) - Changes to Vector representation.&O(1) - Changes to Repa representation.&O(1) - Changes to Repa representation.MChanges computation strategy. Will casue all fused operations to be computed.MChanges computation strategy. Will casue all fused operations to be computed.) !"#$%&'()*+,-./0123456789:&'()*+,-./012354 !"687#$%9:(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone:5Create an image with sequential array representation.3Create an image with parallel array representation.PConstruct an image from a nested rectangular shaped list of pixels sequentially.OConstruct an image from a nested rectangular shaped list of pixels in parallel.(m rows, n& columns) - dimensions of a new image.A function that takes (i -th row, and jB-th column) as an argument and returns a pixel for that location.(m rows, n& columns) - dimensions of a new image.A function that takes (i -th row, and jB-th column) as an argument and returns a pixel for that location.  (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone:Create an image with / (Vector Unboxed) representation and pixels of ;, precision. Note, that it is essential for ;4 precision pixels to keep values normalized in the [0, 1]= range in order for an image to be written to file properly.dlet grad_gray = makeImage (200, 200) (\(i, j) -> PixelY (fromIntegral i)/200 * (fromIntegral j)/200) Because all Us and Cs are installed into ˜, above is equivalent to:Ylet grad_gray = makeImage (200, 200) (\(i, j) -> PixelY $ fromIntegral (i*j)) / (200*200)+writeImage "images/grad_gray.png" grad_gray&Creating color images is just as easy.zlet grad_color = makeImage (200, 200) (\(i, j) -> PixelRGB (fromIntegral i) (fromIntegral j) (fromIntegral (i + j))) / 400-writeImage "images/grad_color.png" grad_color images/grad_gray.png images/grad_color.pngmConstruct an image from a nested rectangular shaped list of pixels. Length of an outer list will constitute m* rows, while the length of inner lists - nJ columns. All of the inner lists must be the same length and greater than 0.QfromLists [[PixelY (fromIntegral (i*j) / 60000) | j <- [1..300]] | i <- [1..200]])<Image VectorUnboxed Y (Double): 200x300> images/grad_fromLists.png(m rows, n& columns) - dimensions of a new image.A function that takes (i -th row, and jB-th column) as an argument and returns a pixel for that location.          (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone9:;<= "Convert any pixel to binary pixel.$Convert a Binary pixel to Luma pixel"Convert any image to binary image.$Convert a Binary image to Luma imageValues are scaled to  [0.0, 1.0] range. Values are scaled to  [0.0, 1.0] range.!Values are scaled to [0, 18446744073709551615] range."Values are scaled to [0, 4294967295] range.#Values are scaled to  [0, 65535] range.$Values are scaled to [0, 255] range.;Computes Luma: + Y' = 0.299 * R' + 0.587 * G' + 0.114 * B' " !"#$%&'()*+,-./0123456789:;<€EJFGHIKLMNSUU­¬ž·ÃÂÏÎÙê非Ÿ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáïðñòóôõö÷øùúûüýþÿtSUMNEFGHIJKLÄÅÁÂß¿À»Œœ·ž¹º²³Žµ¶¯°±¬­®ÑÒÓÔÌÍÎÏÐÉÊËÆÇÈûüýþÿõö÷øùúòóôïðñš©ª«£€¥Š§ ¡¢žŸÕÖרÙÚÛÜÝÞßàá" !"#$%&'()*+,-./0123456789:;<(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone $9:;<=DR=$Tagged Image File Format image with .tif or .tiff extension.?6Truevision Graphics Adapter image with .tga extension.A%Portable Network Graphics image with .png extension.C,Joint Photographic Experts Group image with .jpg or .jpeg extension.EHigh-dynamic-range image with .hdr or .pic extension.G'Graphics Interchange Format image with .gif extension.IBitmap image with .bmp extension.ÿ=>?@ABCDEFGHIJ<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?   ™?=><=>?@ABCDEFGHIJÿÿ=>?@ABCDEFGHIJ@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./10325476<98;:=>=<??>(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 9:;<=DRK#Netpbm: portable pixmap image with .ppm extension.M$Netpbm: portable graymap image with .pgm extension.O#Netpbm: portable bitmap image with .pbm extension.HKLMNOP@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€KLMNOP?KLMNOP@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuwvyx{z}|~€(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 9:;<=DRQQA collection of all image formats that can be written to file using images with ; precision pixels.RIA collection of all image formats that can be read into HIP images with ; precision pixel channels.Q‚ƒ„…†‡ˆR‰Š‹ŒŽS‘TU’V0  ”•–—˜š›œ™?=><=>?@ABCDEFGHIJKLMNOPQR,IJGH EFCDAB?@=>OPMNKLRQ–—”•˜™š›œQ‚ƒ„…†‡ˆR‰Š‹ŒŽST‘UV’(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone: ]:External viewing application to use for displaying images.^*Any custom viewer, which can be specified:FilePath# - to the actual viewer executable.[String]@ - command line arguments that will be passed to the executable.Int* - position index in the above list where “ to an image should be injected_ÿThis function will try to guess an image format from file's extension, then it will attempt to read it as such. It will fall back onto the rest of the supported formats and will try to read them regarless of file's extension. Whenever image cannot be decoded, ”H containing all errors for each attempted format will be returned, and •T containing an image otherwise. Image will be read into a type signature specified S (Ä, Á, · and ² only) with ;2 precision, while doing all necessary conversions.`šThis function allows for reading any supported image in the exact colorspace and precision it is currently encoded in. For instance, frog image can be read into it's š colorspace with 8 precision and into any supported array representation.QreadImageExact JPG "images/frog.jpg" :: IO (Either String (Image RP YCbCr Word8))1Right <Image RepaParallel YCbCr (Word8): 200x320>lThe drawback here is that colorspace and precision has to match exactly, otherwise it will return an error:OreadImageExact JPG "images/frog.jpg" :: IO (Either String (Image RP RGB Word8))‡Left "JuicyPixel decoding error: Input image is in YCbCr8 (Pixel YCbCr Word8), cannot convert it to RGB8 (Pixel RGB Word8) colorspace."„Attempt to read an image in a particular color space that is not supported by the format, will result in a compile error. Refer to –+ class for all images that can be decoded.a Just like _s, this function will guess an output file format from the extension and write to file any image that is in one of Ä, Á, · or ² color spaces with ;œ precision. While doing necessary conversions the choice will be given to the most suited color space supported by the format. For instance, in case of a A format, an (C arr ² ;) would be written as RGBA16G, hence preserving transparency and using highest supported precision +. At the same time, writing that image in G format would save it in RGB8, since  is the highest precision G> supports and it currently cannot be saved with transparency.bÿ3Write an image in a specific format, while supplying any format specific options. Precision and color space, that an image will be written as, is decided from image's type. Attempt to write image file in a format that does not support color space and precision combination will result in a compile error.cAn image is written as a .tiffo file into an operating system's temporary directory and passed as an argument to the external viewer program. d;Displays an image file by calling an external image viewer.e°Makes a call to an external viewer that is set as a default image viewer by the OS. This is a non-blocking function call, so it will take some time before an image will appear.)frog <- readImageRGB VU "images/frog.jpg"displayImage froggeog tmp hip/img.tiff (https://help.gnome.org/users/eog/stable/ Eye of GNOMEhfeh --fullscreen --auto-zoom tmp hip/img.tiff https://feh.finalrewind.org/FEHi gpicview tmp hip/img.tiff %http://lxde.sourceforge.net/gpicview/GPicViewjgimp tmp hip/img.tiff https://www.gimp.org/GIMP]^–_`4A file format that an image should be read as. See #g:4Supported Image FormatsLocation of an image.a*Location where an image should be written.An image to write. b5A file format that an image should be saved in. See #g:4Supported Image Formats"A list of format specific options.*Location where an image should be written.TAn image to write. Can be a list of images in case of formats supporting animation.cExternal viewer to useShould the call be blockingImage to displaydeImage to be displayedfghij>  ”•–—˜™š›œ?=><=>?@ABCDEFGHIJKLMNOPQR]^_`abcdefghij_`ab]^ecdfgihj]^–_`abcdefghij (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone$:T l„For now it is just a type synonym, but in the future it might become a custom data type with fields like title, width, heigth, etc.m'A single channel histogram of an image.oUVector containing pixel counts. Index of a vector serves as an original pixel value.p:Name of the channel that will be displayed in the legend.qColor of a plotted line.r2Create a histogram per channel with 256 bins each.sCGenerate a histogram with 256 bins for a single channel Gray image.t'Write histograms into a PNG image file.)frog <- readImageRGB VU "images/frog.jpg"@writeHistograms "images/frog_histogram.svg" $ getHistograms frog images/frog_histogram.svguODisplay image histograms using an external program. Works in a similar way as e.)frog <- readImageRGB VU "images/frog.jpg"&displayHistograms $ getHistograms frog—ODisplay image histograms using an external program. Works in a similar way as c. lmnopqrstu— lmnopqrstu mnopqlrsutlmnopqrstu— (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone 9:;<=? vvÆ contains a convenient set of functions for binary image construction, which is done by comparing either a single pixel with every pixel in an image or two same size images pointwise. For example:'frog <- readImageY VU "images/frog.jpg"1frog .==. PixelY 0 -- (or: PixelY 0 .==. frog)2frog .<. flipH frog -- (or: flipH frog .>. frog)} Pixel wise AND operator on binary images. ~ Pixel wise OR operator on binary images.'Complement each pixel in a binary image€?Construct a binary image using a predicate from a source image.BConstruct a binary image using a predicate from two source images.‚3Threshold a source image with an applicative pixel.+yield <- readImageRGB VU "images/yield.jpg"dwriteImageExact PNG [] "images/yield_bin.png" $ thresholdWith (PixelRGB (>0.55) (<0.6) (<0.5)) yield images/yield.jpg images/yield_bin.pngƒ?Compare two images with an applicative pixel. Works just like ‚, but on two images.„Erosion is defined as: {E = B "– S = {m,n|S ˜ ™"†B}gwriteImageExact PNG [] "images/figure_erode.png" $ pixelGrid 10 $ fromImageBinary $ erode struct figure images/figure.png eroded with  images/struct.png is images/figure_erode.png…Dialation is defined as: {D = B "• S = {m,n|S ˜ ™")B"`"}kwriteImageExact PNG [] "images/figure_dialate.png" $ pixelGrid 10 $ fromImageBinary $ dialate struct figure images/figure.png dialated with  images/struct.png is images/figure_dialate.png†Opening is defined as: {B %Ë S = (B "– S) "• S}ewriteImageExact PNG [] "images/figure_open.png" $ pixelGrid 10 $ fromImageBinary $ open struct figure images/figure.png opened with  images/struct.png is images/figure_open.png‡Closing is defined as: {B %Ï S = (B "• S) "– S}gwriteImageExact PNG [] "images/figure_close.png" $ pixelGrid 10 $ fromImageBinary $ close struct figure images/figure.png closed with  images/struct.png is images/figure_close.pngvwxyz{|}~€ Predicate Source image. PredicateFirst source image.Second source image.‚5Pixel containing a thresholding function per channel. Source image.ƒ2Pixel containing a comparing function per channel. First image. second image.„Structuring element.Binary source image.…Structuring element.Binary source image.†Structuring element.Binary source image.‡Structuring element.Binary source image.ˆ‰Švwxyz|{}~€‚ƒ„…†‡€‚ƒ}~vwxyz{|„…†‡vwxyz{|}~€‚ƒ„…†‡ˆ‰Šw4x4y4z4{4|4}3~2(c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNoneÀ  .CEJFGHIKLMNSU­¬ž·ÃÂÏÎÙê锕–—˜™š›œ?=><žŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáïðñòóôõö÷øùúûüýþÿ =>?@ABCDEFGHIJKLMNOPQR.  (c) Alexey Kuleshevich 2016BSD3%Alexey Kuleshevich <lehins@yandex.ru> experimental non-portableNone: ‹ Read image as luma (brightness).ŒRead image as luma with M channel.Read image in RGB colorspace.Ž"Read image in RGB colorspace with M channel.#Get the number of rows in an image.)frog <- readImageRGB VU "images/frog.jpg"frog+<Image VectorUnboxed RGB (Double): 200x320> rows frog200&Get the number of columns in an image.)frog <- readImageRGB VU "images/frog.jpg"frog+<Image VectorUnboxed RGB (Double): 200x320> cols frog320‘Sum all pixels in the image.’!Multiply all pixels in the image.“(Retrieve the biggest pixel from an image”)Retrieve the smallest pixel from an image•,Scales all of the pixels to be in the range [0, 1].–0Generates a nested list of pixels from an image.  img == fromLists (toLists img) ‹ŒŽ‘’“”•–,=<:9876543Dabc `abe‹ŒŽ‘’“”•–,–‹ŒŽ`abeDcab3456789:<=‘’“”•  ‹ŒŽ‘’“”•–˜ !" !# !$ !%&'(&')&'*&'+&',&-.&-/&-0&-1&-2&-3&-4&-4 56 5789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜ ™ ™ š š › œ  ž Ÿ   ¡ ¢ £ € ¥ Š § š © ª « ¬ ­ ® ¯ ° ± ²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãääåæçèéêëìíîïðñòóôõõö÷øùúûüýþÿ      !"#$%&''()*+,,--./01234U`56789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWWXXYYZZ[[\\]]^^__``abcdefghijklmmnopqrstuvwxyz { | | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž   ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ¡ ¢ £ €¥Š§ š© ª« ¬­ ®¯ ®° ±² ±³ ®Ž ®µ ¶ · ž ¹ º »ŒœŸ¿¥ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÆÇÑÒÓÔÕÖרÙÚÆÇÛÜÝÞßàáâãÆÇäåæçèéêëÚÆìí ¬îï¥Àðñ òóôõö÷øùúûÆÇüýþÿ¥À¥À¥Š Æ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH¥ÀIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZÚÛÜÝÞ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~HI€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™ š› œ œžŸ  ¡"hip-1.3.0.0-GxchXxb8UabFUDtasJ5Z1vGraphics.Image.ColorSpaceGraphics.Image.IO.FormatsGraphics.Image.InterfaceGraphics.Image.Processing!Graphics.Image.Processing.ComplexGraphics.Image.Interface.VectorGraphics.Image.Interface.RepaGraphics.Image.IOGraphics.Image.IO.Histogram Graphics.Image.Processing.BinaryGraphics.Image'Graphics.Image.Processing.Interpolation#Graphics.Image.Processing.Geometric%Graphics.Image.Processing.ConvolutionGraphics.Image.IO.BaseGraphics.Image.ColorSpace.YCbCrGraphics.Image.ColorSpace.RGBGraphics.Image.ColorSpace.LumaGraphics.Image.ColorSpace.HSIGraphics.Image.ColorSpace.GrayY!Graphics.Image.ColorSpace.Complex)Graphics.Image.Processing.Complex.FourierGraphics.Image.ColorSpace.CMYK Graphics.Image.ColorSpace.Binary(Graphics.Image.Interface.Vector.Unboxing'Graphics.Image.Interface.Vector.Unboxed&Graphics.Image.Interface.Repa.Internal%Graphics.Image.IO.Formats.JuicyPixels Graphics.Image.IO.Formats.NetpbmGraphics.Image.TypesbaseGHC.WordWord8Word16Word32Word64(JuicyPixels-3.2.8-2m7yVK9j51UF1F7dRciij5Codec.Picture.GifGifDelay LoopingRepeatLoopingForever LoopingNever GifLoopingCodec.Picture.ColorQuantUniform MedianMeanCutPaletteCreationMethodpaletteColorCountenableImageDitheringpaletteCreationMethodPaletteOptions Data.Complex:+ComplexBorderFillWrapEdgeReflectContinue ExchangableexchangeMArrayMImage unsafeIndexindex deepSeqImagefoldlfoldr makeImageMmapMmapM_foldMfoldM_mdimsthawfreezenewreadwriteswapArrayManifest makeImage singletonindex00mapimapzipWithizipWithtraverse traverse2 transpose backpermute fromLists|*|foldeqcompute toManifest BaseArrayEltImagedimsElevatortoWord8toWord16toWord32toWord64toFloattoDouble fromDoubleAlphaOpaquegetAlphaaddAlpha dropAlphaopaque ColorSpacePixelEltPixel fromChanneltoEltfromEltgetPxChchOppxOpchApp pxFoldMapcsColour exchangeFromhandleBorderIndex defaultIndex borderIndex maybeIndex $fShowMImage $fShowImage $fNFDataImage$fFloatingImage$fFractionalImage $fNumImage $fEqImage$fBoundedPixel$fFloatingPixel$fFractionalPixel $fNumPixel$fFoldablePixel$fApplicativePixel$fFunctorPixel$fExchangablearrarr $fShowBorderBilinearNearest Interpolation interpolate downsampleF upsampleFdownsampleRowsdownsampleCols downsample upsampleRows upsampleColsupsample leftToRight topToBottom translate canvasSizecrop superimposeflipVflipHrotate90 rotate180 rotate270rotateresizescaleconvolve convolveRows convolveCols pixelGridWritableencodeReadabledecode ImageFormat SaveOptionextextsisFormatToYCbCrA toPixelYCbCrA toImageYCbCrAToYCbCr toPixelYCbCr toImageYCbCrYCbCrA LumaYCbCrA CBlueYCbCrA CRedYCbCrA AlphaYCbCrAYCbCr LumaYCbCr CBlueYCbCr CRedYCbCrToRGBA toPixelRGBA toImageRGBAToRGB toPixelRGB toImageRGBRGBARedRGBA GreenRGBABlueRGBA AlphaRGBARGBRedRGBGreenRGBBlueRGBToYA toPixelYA toImageYAToYtoPixelYtoImageYYAAlphaYAToHSIA toPixelHSIA toImageHSIAToHSI toPixelHSI toImageHSIHSIAHueHSIASatHSIAIntHSIA AlphaHSIAHSIHueHSISatHSIIntHSIGray toGrayImagesfromGrayImages+:realPartimagPartmkPolarcispolar magnitudephase conjugatefftifft!+! realPart' imagPart'mkPolar'cis'polar' magnitude'phase' conjugate' makeFilter applyFilterToCMYKA toPixelCMYKA toImageCMYKAToCMYK toPixelCMYK toImageCMYKCMYKA CyanCMYKAMagCMYKAYelCMYKAKeyCMYKA AlphaCMYKACMYKCyanCMYKMagCMYKYelCMYKKeyCMYKBitBinaryonofffromBoolisOnisOff complementVUtoUnboxedVectorfromUnboxedVectorfromIxtoIxRSRPfromRepaArraySfromRepaArrayP toRepaArray makeImageS makeImageP fromListsS fromListsP toPixelBinaryfromPixelBinary toImageBinaryfromImageBinary$fElevatorDouble$fElevatorFloat$fElevatorWord64$fElevatorWord32$fElevatorWord16$fElevatorWord8 $fToCMYKARGBA $fToCMYKRGB$fToYCbCrARGBA $fToYCbCrRGB $fToHSIARGBA $fToHSIRGB $fToHSIAYA$fToHSIY $fToRGBACMYKA $fToRGBCMYK$fToRGBAYCbCrA $fToRGBYCbCr $fToRGBAHSIA $fToRGBHSI $fToRGBAYA$fToRGBY $fToYAYCbCrA $fToYYCbCr $fToYCMYK $fToYAHSIA$fToYHSI $fToYARGBA$fToYRGB $fToYGrayTIFTGAPNGJPGHDRGIFBMPPPMPGMPBM OutputFormat InputFormat$fWritableImageOutputFormat$fImageFormatOutputFormat$fReadableImageInputFormat$fImageFormatInputFormat$fShowInputFormat$fEnumInputFormat$fEqInputFormat$fShowOutputFormat$fEnumOutputFormat$fEqOutputFormatExternalViewer readImagereadImageExact writeImagewriteImageExactdisplayImageUsingdisplayImageFile displayImage defaultViewer eogViewer fehViewergpicviewViewer gimpViewer$fShowExternalViewer Histograms HistogramhBinshNamehColour getHistograms getHistogramwriteHistogramsdisplayHistograms Thresholding.==../=..<..<=..>..>=..&&..||.inverttoImageBinaryUsingtoImageBinaryUsing2 thresholdWith compareWitherodedialateopenclose$fThresholdingImagePixelarr$fThresholdingPixelImagearr$fThresholdingImageImagearr readImageY readImageYA readImageRGB readImageRGBArowscolssumproductmaximumminimum normalizetoListsghc-prim GHC.ClassesEqGHC.NumNumGHC.Real Fractional GHC.FloatFloatingGHC.BaseFunctor Applicative Data.FoldableFoldablefoldMapNothingJust$fInterpolationBilinear$fInterpolationNearest angle0to2pisin'cos' flipUsing convolve''bytestring-0.10.8.1Data.ByteString.Lazy.Internal ByteString GHC.TypesTrue Convertibleconvert PixelYCbCrA PixelYCbCr $fShowPixel $fShowPixel0 $fShowYCbCrA $fShowYCbCr $fAlphaYCbCrAD:R:PixelYCbCrAe0$fColorSpaceYCbCrAD:R:PixelYCbCre0$fColorSpaceYCbCr PixelRGBAPixelRGB $fShowRGBA $fShowRGB $fAlphaRGBAD:R:PixelRGBAe0$fColorSpaceRGBAD:R:PixelRGBe0$fColorSpaceRGBPixelYAPixelY $fMonadPixel$fShowYA$fShowY $fAlphaYA D:R:PixelYAe0$fColorSpaceYA D:R:PixelYe0 $fColorSpaceY PixelHSIAPixelHSI $fShowHSIA $fShowHSI $fAlphaHSIAD:R:PixelHSIAe0$fColorSpaceHSIAD:R:PixelHSIe0$fColorSpaceHSI PixelGrayD:R:PixelGraye0$fColorSpaceGraypi isPowerOfTwoIntfft2dGHC.ErrerrorModeForwardInverse signOfMode fftGeneraltwiddle PixelCMYKA PixelCMYK $fShowCMYKA $fShowCMYK $fAlphaCMYKAD:R:PixelCMYKAe0$fColorSpaceCMYKAD:R:PixelCMYKe0$fColorSpaceCMYKFalseBoolnot PixelBinary$fNumBitD:R:PixelBinarye0$fColorSpaceBinary $fUnboxPixel $fUnboxBitV_PixelMV_PixelV_BitMV_Bit$fVectorVectorPixelD:R:VectorPixel0$fMVectorMVectorPixelD:R:MVectorsPixel0$fVectorVectorBitD:R:VectorBit0$fMVectorMVectorBitD:R:MVectorsBit0&vector-0.11.0.0-6uB77qGCxR6GPLxI2sqsX3Data.Vector.Unboxed.BaseMVectorVectorMVImageMVScalarVScalarVUImage checkDimsD:R:MImagestVUcse0 $fMArrayVUcse $fArrayVUcseD:R:ImageVUcse0$fBaseArrayVUcse$fShowVU izipWithR$fExchangableRPVU$fExchangableRSVU$fExchangableVURP$fExchangableVURS$fExchangableRSRP$fExchangableRPRSPScalarPUImagePDImageSScalarSUImageSDImagesh2dimsdims2shimapR traverseR traverse2R backpermuteR fromListsRmultR singletonR getDelayedS getDelayedP $fEltPixel$fEltBit $fArrayRPcseD:R:ImageRPcse0$fBaseArrayRPcse $fArrayRScseD:R:ImageRScse0$fBaseArrayRScse$fShowRS$fShowRPDouble JPGQuality GIFsPalette GIFsLooping GIFPalette decodeGifsjpImageToImagejpImageY8ToImagejpImageY16ToImagejpImageYA8ToImagejpImageYA16ToImagejpImageRGB8ToImagejpImageRGB16ToImagejpImageRGBFToImagejpImageRGBA8ToImagejpImageRGBA16ToImagejpImageYCbCr8ToImagejpImageCMYK8ToImagejpImageCMYK16ToImagejpDynamicImageToImage'jpDynamicImageToImage jpImageShowCSjpError jpCSError encodeGIF encodeGIFs encodeJPGimageToJPImage$fWritableImageTIF$fWritableImageTIF0$fWritableImageTIF1$fWritableImageTIF2$fWritableImageTIF3$fWritableImageTIF4$fWritableImageTIF5$fWritableImageTIF6$fWritableImageTIF7$fWritableImageTIF8$fWritableImageTIF9$fWritableImageTIF10$fWritableImageTIF11$fWritableImageTIF12$fWritableImageTIF13$fWritableImageTIF14$fWritableImageTIF15$fWritableImageTIF16$fWritableImageTGA$fWritableImageTGA0$fWritableImageTGA1$fWritableImageTGA2$fWritableImageTGA3$fWritableImageTGA4$fWritableImageTGA5$fWritableImageTGA6$fWritableImagePNG$fWritableImagePNG0$fWritableImagePNG1$fWritableImagePNG2$fWritableImagePNG3$fWritableImagePNG4$fWritableImagePNG5$fWritableImagePNG6$fWritableImagePNG7$fWritableImagePNG8$fWritableImagePNG9$fWritableImagePNG10$fWritableImagePNG11$fWritableImageJPG$fWritableImageJPG0$fWritableImageJPG1$fWritableImageJPG2$fWritableImageJPG3$fWritableImageJPG4$fWritableImageJPG5$fWritableImageJPG6$fWritableImageHDR$fWritableImageHDR0$fWritableImageHDR1$fWritableImageHDR2$fWritableImageHDR3$fWritable[][]$fWritable[][]0$fWritableImageGIF$fWritableImageGIF0$fWritableImageGIF1$fWritableImageGIF2$fWritableImageGIF3$fWritableImageBMP$fWritableImageBMP0$fWritableImageBMP1$fWritableImageBMP2$fWritableImageBMP3$fWritableImageBMP4$fWritableImageBMP5$fWritableImageBMP6$fReadableImageTIF$fReadableImageTIF0$fReadableImageTIF1$fReadableImageTIF2$fReadableImageTIF3$fReadableImageTIF4$fReadableImageTIF5$fReadableImageTIF6$fReadableImageTIF7$fReadableImageTIF8$fReadableImageTIF9$fReadableImageTIF10$fReadableImageTIF11$fReadableImageTIF12$fReadableImageTIF13$fReadableImageTGA$fReadableImageTGA0$fReadableImageTGA1$fReadableImageTGA2$fReadableImageTGA3$fReadableImageTGA4$fReadableImageTGA5$fReadableImageTGA6$fReadableImagePNG$fReadableImagePNG0$fReadableImagePNG1$fReadableImagePNG2$fReadableImagePNG3$fReadableImagePNG4$fReadableImagePNG5$fReadableImagePNG6$fReadableImagePNG7$fReadableImagePNG8$fReadableImagePNG9$fReadableImagePNG10$fReadableImagePNG11$fReadableImageJPG$fReadableImageJPG0$fReadableImageJPG1$fReadableImageJPG2$fReadableImageJPG3$fReadableImageJPG4$fReadableImageJPG5$fReadableImageJPG6$fReadableImageJPG7$fReadableImageHDR$fReadableImageHDR0$fReadableImageHDR1$fReadableImageHDR2$fReadableImageHDR3$fReadable[][]$fReadable[][]0$fReadable[][]1$fReadable[][]2$fReadable[][]3$fReadable[][]4$fReadableImageGIF$fReadableImageGIF0$fReadableImageGIF1$fReadableImageGIF2$fReadableImageGIF3$fReadableImageGIF4$fReadableImageBMP$fReadableImageBMP0$fReadableImageBMP1$fReadableImageBMP2$fReadableImageBMP3$fReadableImageBMP4$fReadableImageBMP5$fReadableImageBMP6$fConvertiblePixelPixelCMYK16$fConvertiblePixelPixelCMYK8$fConvertiblePixelPixelYCbCr8$fConvertiblePixelPixelRGBA16$fConvertiblePixelPixelRGBA8$fConvertiblePixelPixelRGBF$fConvertiblePixelPixelRGB16$fConvertiblePixelPixelRGB8$fConvertiblePixelPixelYA16$fConvertiblePixelPixelYA8$fConvertiblePixelFloat$fConvertiblePixelWord32$fConvertiblePixelWord16$fConvertiblePixelWord8$fConvertiblePixelCMYK16Pixel$fConvertiblePixelCMYK8Pixel$fConvertiblePixelYCbCr8Pixel$fConvertiblePixelRGBA16Pixel$fConvertiblePixelRGBA8Pixel$fConvertiblePixelRGBFPixel$fConvertiblePixelRGB16Pixel$fConvertiblePixelRGB8Pixel$fConvertiblePixelYA16Pixel$fConvertiblePixelYA8Pixel$fConvertibleFloatPixel$fConvertibleWord32Pixel$fConvertibleWord16Pixel$fConvertibleWord8Pixel$fConvertiblePixelRGBA16Pixel0$fConvertiblePixelRGBA8Pixel0$fConvertiblePixelYCbCr8Pixel0$fConvertiblePixelCMYK16Pixel0$fConvertiblePixelCMYK8Pixel0$fConvertiblePixelRGBFPixel0$fConvertiblePixelRGB16Pixel0$fConvertiblePixelRGB8Pixel0$fConvertiblePixelYA16Pixel0$fConvertiblePixelYA8Pixel0$fConvertibleFloatPixel0$fConvertibleWord16Pixel0$fConvertibleWord8Pixel0$fConvertiblePixelCMYK16Pixel1$fConvertiblePixelCMYK8Pixel1$fConvertiblePixelYCbCr8Pixel1$fConvertiblePixelRGBFPixel1$fConvertiblePixelRGBA16Pixel1$fConvertiblePixelRGBA8Pixel1$fConvertiblePixelRGB16Pixel1$fConvertiblePixelRGB8Pixel1$fConvertiblePixelYA16Pixel1$fConvertiblePixelYA8Pixel1$fConvertibleFloatPixel1$fConvertibleWord16Pixel1$fConvertibleWord8Pixel1$fConvertiblePixelRGBA16Pixel2$fConvertiblePixelRGBA8Pixel2$fConvertiblePixelYCbCr8Pixel2$fConvertiblePixelCMYK16Pixel2$fConvertiblePixelCMYK8Pixel2$fConvertiblePixelRGBFPixel2$fConvertiblePixelRGB16Pixel2$fConvertiblePixelRGB8Pixel2$fConvertiblePixelYCbCr8Pixel3$fConvertiblePixelCMYK16Pixel3$fConvertiblePixelCMYK8Pixel3$fConvertiblePixelRGBFPixel3$fConvertiblePixelRGBA16Pixel3$fConvertiblePixelRGBA8Pixel3$fConvertiblePixelRGB16Pixel3$fConvertiblePixelRGB8Pixel3$fConvertiblePixelYA16Pixel2$fConvertiblePixelYA8Pixel2$fConvertibleFloatPixel2$fConvertibleWord16Pixel2$fConvertibleWord8Pixel2$fConvertiblePixelYA16Pixel3$fConvertiblePixelYA8Pixel3$fConvertibleFloatPixel3$fConvertibleWord16Pixel3$fConvertibleWord8Pixel3D:R:SaveOptionTIF0$fImageFormatTIFD:R:SaveOptionTGA0$fImageFormatTGAD:R:SaveOptionPNG0$fImageFormatPNGD:R:SaveOptionJPG0$fImageFormatJPGD:R:SaveOptionHDR0$fImageFormatHDRD:R:SaveOption[]0$fImageFormat[]D:R:SaveOptionGIF0$fImageFormatGIFD:R:SaveOptionBMP0$fImageFormatBMPpnmToImagesUsinggetPxpnmDataToImagepnmDataPBMToImagepnmDataPGM8ToImagepnmDataPGM16ToImagepnmDataPPM8ToImagepnmDataPPM16ToImageppmToImageUsing decodePnmpnmError pnmCSError pnmShowData$fReadableImagePPM$fReadableImagePPM0$fReadableImagePGM$fReadableImagePGM0$fReadableImagePBM$fReadableImagePPM1$fReadableImagePPM2$fReadableImagePPM3$fReadableImagePPM4$fReadableImagePGM1$fReadableImagePBM0$fConvertiblePpmPixelRGB16Pixel$fConvertiblePpmPixelRGB8Pixel$fConvertiblePgmPixel16Pixel$fConvertiblePgmPixel8Pixel$fConvertiblePbmPixelPixel $fConvertiblePpmPixelRGB16Pixel0$fConvertiblePpmPixelRGB8Pixel0$fConvertiblePgmPixel16Pixel0$fConvertiblePgmPixel8Pixel0$fConvertiblePbmPixelPixel0 $fConvertiblePpmPixelRGB16Pixel1$fConvertiblePpmPixelRGB8Pixel1$fConvertiblePgmPixel16Pixel1$fConvertiblePgmPixel8Pixel1$fConvertiblePbmPixelPixel1 $fConvertiblePpmPixelRGB16Pixel2$fConvertiblePpmPixelRGB8Pixel2$fConvertiblePgmPixel16Pixel2$fConvertiblePgmPixel8Pixel2$fConvertiblePbmPixelPixel2 $fConvertiblePpmPixelRGB16Pixel3$fConvertiblePpmPixelRGB8Pixel3$fConvertiblePgmPixel16Pixel3$fConvertiblePgmPixel8Pixel3$fConvertiblePbmPixelPixel3D:R:SaveOption[]2$fImageFormat[]0D:R:SaveOption[]4$fImageFormat[]1D:R:SaveOptionPPM0$fImageFormatPPMD:R:SaveOptionPGM0$fImageFormatPGMD:R:SaveOptionPBM0$fImageFormatPBM OutputBMP OutputGIF OutputHDR OutputJPG OutputPNG OutputTIF OutputTGAInputBMPInputGIFInputHDRInputJPGInputPNGInputTIFInputPNMInputTGAD:R:SaveOptionOutputFormat0D:R:SaveOptionInputFormat0GHC.IOFilePath Data.EitherLeftRight guessFormatdisplayHistogramsUsing