JuicyPixels 3.1.3.3 → 3.1.4
raw patch · 8 files changed
+387/−37 lines, 8 filesbinary-added
Files
- JuicyPixels.cabal +4/−3
- changelog +8/−0
- docimages/juicy.png binary
- docimages/pixelgraph.svg +264/−0
- src/Codec/Picture.hs +1/−1
- src/Codec/Picture/Bitmap.hs +32/−9
- src/Codec/Picture/ConvGraph.hs +2/−1
- src/Codec/Picture/Types.hs +76/−23
JuicyPixels.cabal view
@@ -1,8 +1,8 @@ Name: JuicyPixels -Version: 3.1.3.3 +Version: 3.1.4 Synopsis: Picture loading/serialization (in png, jpeg, bitmap, gif, tiff and radiance) Description: - <<data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADABAMAAACg8nE0AAAAElBMVEUAAABJqDSTWEL/qyb///8AAABH/1GTAAAAAXRSTlMAQObYZgAAAN5JREFUeF7s1sEJgFAQxFBbsAV72v5bEVYWPwT/XDxmCsi7zvHXavYREBDI3XP2GgICqBBYuwIC+/rVayPUAyAg0HvIXBcQoDFDGnUBgWQQ2Bx3AYFaRoBpAQHWb3bt2ARgGAiCYFFuwf3X5HA/McgGJWI2FdykCv4aBYzmKwDwvl6NVmUAAK2vlwEALK7fo88GANB6HQsAAAAAAAAA7P94AQCzswEAAAAAAAAAAAAAAAAAAICzh4UAO4zWAYBfRutHA4Bn5C69JhowAMGoBaMWDG0wCkbBKBgFo2AUAACPmegUST/IJAAAAABJRU5ErkJggg==>> + <<docimages/juicy.png>> . This library can load and store images in PNG,Bitmap, Jpeg, Radiance, Tiff and Gif images. @@ -17,7 +17,8 @@ -- Constraint on the version of Cabal needed to build this package. Cabal-version: >= 1.10 -Extra-source-files: changelog +extra-source-files: changelog, docimages/*.png, docimages/*.svg +extra-doc-files: docimages/*.png, docimages/*.svg Source-Repository head Type: git
changelog view
@@ -1,5 +1,13 @@ -*-change-log-*- +v3.1.4 February 2014 + * Adding a pixelOpacity method to the pixel type class. + * Adding handling greyscale BMP files (phischu) + * Fixing promotePixel for Pixel8 -> Pixel16 + * Some type fixes in the documentation + * Updating the pixel conversion graph + * Removed URI-encoded images, now using clean cabal embedding + v3.1.3.3 February 2014 * Lowering cabal version limit to be compiled with older GHCs
+ docimages/juicy.png view
binary file changed (absent → 322 bytes)
+ docimages/pixelgraph.svg view
@@ -0,0 +1,264 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.22.2 (20090313.1817) + --> +<!-- Title: pixelGraphic Pages: 1 --> +<svg width="620pt" height="464pt" + viewBox="0.00 0.00 620.00 464.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 460)"> +<title>pixelGraphic</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-460 617,-460 617,5 -4,5"/> +<!-- PixelRGB8 --> +<g id="node1" class="node"><title>PixelRGB8</title> +<ellipse fill="none" stroke="black" cx="246" cy="-438" rx="31.7878" ry="18"/> +<text text-anchor="middle" x="246" y="-436.3" font-family="sans-serif" font-size="8.00">PixelRGB8</text> +</g> +<!-- PixelRGBA8 --> +<g id="node6" class="node"><title>PixelRGBA8</title> +<ellipse fill="none" stroke="black" cx="441" cy="-354" rx="34.8223" ry="18"/> +<text text-anchor="middle" x="441" y="-352.3" font-family="sans-serif" font-size="8.00">PixelRGBA8</text> +</g> +<!-- PixelRGB8->PixelRGBA8 --> +<g id="edge4" class="edge"><title>PixelRGB8->PixelRGBA8</title> +<path fill="none" stroke="black" d="M274.25,-429.506C295.421,-422.833 324.934,-412.874 350,-402 351.523,-401.339 381.994,-385.244 407.261,-371.871"/> +<polygon fill="black" stroke="black" points="409.071,-374.874 416.272,-367.102 405.796,-368.687 409.071,-374.874"/> +<text text-anchor="middle" x="393" y="-394.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- PixelRGBF --> +<g id="node8" class="node"><title>PixelRGBF</title> +<ellipse fill="none" stroke="black" cx="33" cy="-102" rx="31.7878" ry="18"/> +<text text-anchor="middle" x="33" y="-100.3" font-family="sans-serif" font-size="8.00">PixelRGBF</text> +</g> +<!-- PixelRGB8->PixelRGBF --> +<g id="edge6" class="edge"><title>PixelRGB8->PixelRGBF</title> +<path fill="none" stroke="black" d="M214.594,-434.005C148.276,-424.689 0,-398.847 0,-354 0,-354 0,-354 0,-186 0,-165.437 8.67323,-143.88 17.1268,-127.753"/> +<polygon fill="black" stroke="black" points="20.228,-129.378 22.0115,-118.934 14.1045,-125.986 20.228,-129.378"/> +<text text-anchor="middle" x="23" y="-268.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel8 --> +<g id="node20" class="node"><title>Pixel8</title> +<ellipse fill="none" stroke="black" cx="308" cy="-270" rx="27" ry="18"/> +<text text-anchor="middle" x="308" y="-268.3" font-family="sans-serif" font-size="8.00">Pixel8</text> +</g> +<!-- PixelRGB8->Pixel8 --> +<g id="edge60" class="edge"><title>PixelRGB8->Pixel8</title> +<path fill="none" stroke="black" d="M214.516,-433.811C149.341,-423.852 9.37863,-395.049 55,-336 81.2893,-301.973 207.23,-282.163 270.929,-274.163"/> +<polygon fill="black" stroke="black" points="271.46,-277.624 280.961,-272.936 270.61,-270.676 271.46,-277.624"/> +<text text-anchor="middle" x="80" y="-352.3" font-family="sans-serif" font-size="8.00">computeLuma</text> +</g> +<!-- PixelCMYK8 --> +<g id="node28" class="node"><title>PixelCMYK8</title> +<ellipse fill="none" stroke="black" cx="253" cy="-354" rx="34.8223" ry="18"/> +<text text-anchor="middle" x="253" y="-352.3" font-family="sans-serif" font-size="8.00">PixelCMYK8</text> +</g> +<!-- PixelRGB8->PixelCMYK8 --> +<g id="edge40" class="edge"><title>PixelRGB8->PixelCMYK8</title> +<path fill="none" stroke="black" d="M224.748,-423.894C213.935,-414.831 204.182,-402.459 210,-390 212.758,-384.095 217.013,-378.817 221.794,-374.241"/> +<polygon fill="black" stroke="black" points="224.225,-376.77 229.601,-367.64 219.705,-371.424 224.225,-376.77"/> +<text text-anchor="middle" x="232" y="-394.3" font-family="sans-serif" font-size="8.00">convertPixel</text> +</g> +<!-- PixelYCbCr8 --> +<g id="node30" class="node"><title>PixelYCbCr8</title> +<ellipse fill="none" stroke="black" cx="150" cy="-354" rx="35.9084" ry="18"/> +<text text-anchor="middle" x="150" y="-352.3" font-family="sans-serif" font-size="8.00">PixelYCbCr8</text> +</g> +<!-- PixelRGB8->PixelYCbCr8 --> +<g id="edge42" class="edge"><title>PixelRGB8->PixelYCbCr8</title> +<path fill="none" stroke="black" d="M214.399,-434.415C177.053,-429.451 118.29,-419.109 105,-402 97.106,-391.837 104.874,-381.324 116.049,-372.736"/> +<polygon fill="black" stroke="black" points="118.35,-375.401 124.612,-366.856 114.387,-369.631 118.35,-375.401"/> +<text text-anchor="middle" x="127" y="-394.3" font-family="sans-serif" font-size="8.00">convertPixel</text> +</g> +<!-- PixelRGB16 --> +<g id="node2" class="node"><title>PixelRGB16</title> +<ellipse fill="none" stroke="black" cx="429" cy="-102" rx="34.1425" ry="18"/> +<text text-anchor="middle" x="429" y="-100.3" font-family="sans-serif" font-size="8.00">PixelRGB16</text> +</g> +<!-- PixelRGBA16 --> +<g id="node4" class="node"><title>PixelRGBA16</title> +<ellipse fill="none" stroke="black" cx="343" cy="-18" rx="37.1721" ry="18"/> +<text text-anchor="middle" x="343" y="-16.3" font-family="sans-serif" font-size="8.00">PixelRGBA16</text> +</g> +<!-- PixelRGB16->PixelRGBA16 --> +<g id="edge2" class="edge"><title>PixelRGB16->PixelRGBA16</title> +<path fill="none" stroke="black" d="M400.098,-92.2134C386.67,-86.4097 371.409,-77.8363 361,-66 355.909,-60.2106 352.202,-52.8433 349.526,-45.6287"/> +<polygon fill="black" stroke="black" points="352.846,-44.5187 346.482,-36.0479 346.174,-46.6383 352.846,-44.5187"/> +<text text-anchor="middle" x="384" y="-58.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel16 --> +<g id="node16" class="node"><title>Pixel16</title> +<ellipse fill="none" stroke="black" cx="296" cy="-186" rx="27" ry="18"/> +<text text-anchor="middle" x="296" y="-184.3" font-family="sans-serif" font-size="8.00">Pixel16</text> +</g> +<!-- PixelRGB16->Pixel16 --> +<g id="edge58" class="edge"><title>PixelRGB16->Pixel16</title> +<path fill="none" stroke="black" d="M424.573,-120.149C421.265,-130.199 415.765,-142.199 407,-150 386.436,-168.304 356.427,-177.32 332.795,-181.75"/> +<polygon fill="black" stroke="black" points="332.056,-178.325 322.773,-183.431 333.214,-185.228 332.056,-178.325"/> +<text text-anchor="middle" x="441" y="-142.3" font-family="sans-serif" font-size="8.00">computeLuma</text> +</g> +<!-- PixelCMYK16 --> +<g id="node26" class="node"><title>PixelCMYK16</title> +<ellipse fill="none" stroke="black" cx="553" cy="-18" rx="37.1721" ry="18"/> +<text text-anchor="middle" x="553" y="-16.3" font-family="sans-serif" font-size="8.00">PixelCMYK16</text> +</g> +<!-- PixelRGB16->PixelCMYK16 --> +<g id="edge38" class="edge"><title>PixelRGB16->PixelCMYK16</title> +<path fill="none" stroke="black" d="M451.832,-88.3606C462.615,-81.7841 475.593,-73.6731 487,-66 499.46,-57.6189 512.915,-47.9503 524.406,-39.4968"/> +<polygon fill="black" stroke="black" points="526.807,-42.074 532.761,-33.3106 522.641,-36.4482 526.807,-42.074"/> +<text text-anchor="middle" x="525" y="-58.3" font-family="sans-serif" font-size="8.00">convertPixel</text> +</g> +<!-- PixelRGBA16->PixelRGB16 --> +<g id="edge44" class="edge"><title>PixelRGBA16->PixelRGB16</title> +<path fill="none" stroke="black" d="M371.789,-29.3863C383.871,-35.2918 397.329,-43.4955 407,-54 412.378,-59.8422 416.636,-67.2266 419.915,-74.4406"/> +<polygon fill="black" stroke="black" points="416.794,-76.0584 423.794,-84.0115 423.282,-73.4291 416.794,-76.0584"/> +<text text-anchor="middle" x="449" y="-58.3" font-family="sans-serif" font-size="8.00">dropTransparency</text> +</g> +<!-- PixelRGBA8->PixelRGB8 --> +<g id="edge46" class="edge"><title>PixelRGBA8->PixelRGB8</title> +<path fill="none" stroke="black" d="M437.029,-372.038C433.845,-382.309 428.318,-394.571 419,-402 399.083,-417.88 332.208,-428.306 287.678,-433.672"/> +<polygon fill="black" stroke="black" points="287.239,-430.2 277.712,-434.834 288.05,-437.153 287.239,-430.2"/> +<text text-anchor="middle" x="463" y="-394.3" font-family="sans-serif" font-size="8.00">dropTransparency</text> +</g> +<!-- PixelRGBA8->Pixel8 --> +<g id="edge52" class="edge"><title>PixelRGBA8->Pixel8</title> +<path fill="none" stroke="black" d="M413.829,-342.599C399.476,-336.131 381.815,-327.451 367,-318 354.878,-310.267 342.394,-300.428 332.048,-291.673"/> +<polygon fill="black" stroke="black" points="334.114,-288.833 324.258,-284.946 329.539,-294.131 334.114,-288.833"/> +<text text-anchor="middle" x="392" y="-310.3" font-family="sans-serif" font-size="8.00">computeLuma</text> +</g> +<!-- PixelF --> +<g id="node14" class="node"><title>PixelF</title> +<ellipse fill="none" stroke="black" cx="106" cy="-186" rx="27" ry="18"/> +<text text-anchor="middle" x="106" y="-184.3" font-family="sans-serif" font-size="8.00">PixelF</text> +</g> +<!-- PixelRGBF->PixelF --> +<g id="edge56" class="edge"><title>PixelRGBF->PixelF</title> +<path fill="none" stroke="black" d="M27.0137,-120.147C24.9943,-129.716 24.4635,-141.251 30,-150 38.9021,-164.067 54.9514,-172.745 70.015,-178.044"/> +<polygon fill="black" stroke="black" points="69.0981,-181.424 79.6867,-181.06 71.1825,-174.741 69.0981,-181.424"/> +<text text-anchor="middle" x="55" y="-142.3" font-family="sans-serif" font-size="8.00">computeLuma</text> +</g> +<!-- PixelYA16 --> +<g id="node9" class="node"><title>PixelYA16</title> +<ellipse fill="none" stroke="black" cx="259" cy="-102" rx="31.7878" ry="18"/> +<text text-anchor="middle" x="259" y="-100.3" font-family="sans-serif" font-size="8.00">PixelYA16</text> +</g> +<!-- PixelYA16->PixelRGBA16 --> +<g id="edge8" class="edge"><title>PixelYA16->PixelRGBA16</title> +<path fill="none" stroke="black" d="M258.152,-83.5434C258.613,-73.883 260.687,-62.36 267,-54 275.273,-43.0444 287.722,-35.28 300.163,-29.8405"/> +<polygon fill="black" stroke="black" points="301.586,-33.0421 309.607,-26.1198 299.02,-26.5294 301.586,-33.0421"/> +<text text-anchor="middle" x="290" y="-58.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- PixelYA16->Pixel16 --> +<g id="edge48" class="edge"><title>PixelYA16->Pixel16</title> +<path fill="none" stroke="black" d="M229.98,-109.854C206.015,-117.845 177.897,-131.656 191,-150 199.293,-161.611 233.125,-171.835 260.175,-178.391"/> +<polygon fill="black" stroke="black" points="259.609,-181.853 270.143,-180.72 261.201,-175.037 259.609,-181.853"/> +<text text-anchor="middle" x="225" y="-142.3" font-family="sans-serif" font-size="8.00">dropTransparency</text> +</g> +<!-- PixelYA8 --> +<g id="node11" class="node"><title>PixelYA8</title> +<ellipse fill="none" stroke="black" cx="439" cy="-186" rx="28.8445" ry="18"/> +<text text-anchor="middle" x="439" y="-184.3" font-family="sans-serif" font-size="8.00">PixelYA8</text> +</g> +<!-- PixelYA8->PixelRGB8 --> +<g id="edge12" class="edge"><title>PixelYA8->PixelRGB8</title> +<path fill="none" stroke="black" d="M464.762,-194.278C489.627,-203.81 525.815,-222.121 542,-252 574.918,-312.769 554.613,-358.387 501,-402 484.752,-415.217 355.671,-428.373 287.639,-434.476"/> +<polygon fill="black" stroke="black" points="287.321,-430.99 277.669,-435.359 287.938,-437.963 287.321,-430.99"/> +<text text-anchor="middle" x="580" y="-310.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- PixelYA8->PixelRGBA8 --> +<g id="edge10" class="edge"><title>PixelYA8->PixelRGBA8</title> +<path fill="none" stroke="black" d="M460.035,-198.84C467.824,-204.817 475.781,-212.68 480,-222 497.598,-260.871 496.093,-278.904 479,-318 476.725,-323.204 473.295,-328.013 469.411,-332.309"/> +<polygon fill="black" stroke="black" points="466.792,-329.975 462.079,-339.464 471.681,-334.985 466.792,-329.975"/> +<text text-anchor="middle" x="515" y="-268.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- PixelYA8->Pixel8 --> +<g id="edge50" class="edge"><title>PixelYA8->Pixel8</title> +<path fill="none" stroke="black" d="M412.102,-193.018C393.267,-198.789 368.145,-208.269 349,-222 340.05,-228.419 331.808,-237.196 325.098,-245.49"/> +<polygon fill="black" stroke="black" points="322.247,-243.456 318.929,-253.518 327.797,-247.721 322.247,-243.456"/> +<text text-anchor="middle" x="383" y="-226.3" font-family="sans-serif" font-size="8.00">dropTransparency</text> +</g> +<!-- PixelYA8->Pixel8 --> +<g id="edge62" class="edge"><title>PixelYA8->Pixel8</title> +<path fill="none" stroke="black" d="M434.558,-204.131C431.244,-214.175 425.744,-226.175 417,-234 397.039,-251.864 367.99,-260.893 344.899,-265.441"/> +<polygon fill="black" stroke="black" points="344.002,-262.045 334.763,-267.23 345.219,-268.938 344.002,-262.045"/> +<text text-anchor="middle" x="451" y="-226.3" font-family="sans-serif" font-size="8.00">computeLuma</text> +</g> +<!-- PixelF->PixelRGBF --> +<g id="edge14" class="edge"><title>PixelF->PixelRGBF</title> +<path fill="none" stroke="black" d="M100.45,-168.312C96.8232,-158.653 91.3784,-146.886 84,-138 78.5966,-131.492 71.7476,-125.606 64.8367,-120.568"/> +<polygon fill="black" stroke="black" points="66.3898,-117.392 56.1539,-114.657 62.4504,-123.178 66.3898,-117.392"/> +<text text-anchor="middle" x="115" y="-142.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel16->PixelRGB16 --> +<g id="edge18" class="edge"><title>Pixel16->PixelRGB16</title> +<path fill="none" stroke="black" d="M313.43,-172.019C326.239,-162.023 344.257,-148.532 361,-138 371.689,-131.277 383.756,-124.61 394.725,-118.875"/> +<polygon fill="black" stroke="black" points="396.336,-121.982 403.628,-114.295 393.134,-115.757 396.336,-121.982"/> +<text text-anchor="middle" x="384" y="-142.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel16->PixelRGBA16 --> +<g id="edge16" class="edge"><title>Pixel16->PixelRGBA16</title> +<path fill="none" stroke="black" d="M305.084,-168.741C307.903,-162.903 310.835,-156.272 313,-150 325.048,-115.091 333.609,-73.3023 338.424,-46.2333"/> +<polygon fill="black" stroke="black" points="341.89,-46.732 340.143,-36.2822 334.992,-45.5405 341.89,-46.732"/> +<text text-anchor="middle" x="353" y="-100.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel16->PixelYA16 --> +<g id="edge20" class="edge"><title>Pixel16->PixelYA16</title> +<path fill="none" stroke="black" d="M280.78,-170.7C275.635,-164.701 270.35,-157.469 267,-150 264.277,-143.93 262.473,-137.052 261.279,-130.438"/> +<polygon fill="black" stroke="black" points="264.727,-129.827 259.862,-120.415 257.796,-130.807 264.727,-129.827"/> +<text text-anchor="middle" x="290" y="-142.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel8->PixelRGB8 --> +<g id="edge24" class="edge"><title>Pixel8->PixelRGB8</title> +<path fill="none" stroke="black" d="M312.919,-288.095C319.136,-314.953 326.712,-366.057 306,-402 300.622,-411.332 291.773,-418.518 282.501,-423.926"/> +<polygon fill="black" stroke="black" points="280.83,-420.85 273.581,-428.577 284.067,-427.057 280.83,-420.85"/> +<text text-anchor="middle" x="342" y="-352.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel8->PixelRGBA8 --> +<g id="edge22" class="edge"><title>Pixel8->PixelRGBA8</title> +<path fill="none" stroke="black" d="M334.939,-272.185C360.073,-275.561 397.177,-284.15 421,-306 426.855,-311.37 431.048,-318.72 434.03,-326.054"/> +<polygon fill="black" stroke="black" points="430.836,-327.531 437.387,-335.858 437.458,-325.263 430.836,-327.531"/> +<text text-anchor="middle" x="452" y="-310.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel8->PixelYA8 --> +<g id="edge26" class="edge"><title>Pixel8->PixelYA8</title> +<path fill="none" stroke="black" d="M290.77,-255.865C280.734,-245.919 271.57,-232.553 280,-222 287.559,-212.538 356.092,-199.635 400.682,-192.122"/> +<polygon fill="black" stroke="black" points="401.335,-195.562 410.626,-190.469 400.187,-188.657 401.335,-195.562"/> +<text text-anchor="middle" x="303" y="-226.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel8->PixelF --> +<g id="edge28" class="edge"><title>Pixel8->PixelF</title> +<path fill="none" stroke="black" d="M281.145,-267.812C249.741,-264.331 196.969,-255.554 157,-234 145.577,-227.84 134.814,-218.473 126.146,-209.643"/> +<polygon fill="black" stroke="black" points="128.492,-207.028 119.104,-202.117 123.381,-211.81 128.492,-207.028"/> +<text text-anchor="middle" x="180" y="-226.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- Pixel8->Pixel16 --> +<g id="edge30" class="edge"><title>Pixel8->Pixel16</title> +<path fill="none" stroke="black" d="M282.206,-263.957C256.398,-257.327 219.359,-246.018 211,-234 196.025,-212.469 230.216,-199.429 259.604,-192.482"/> +<polygon fill="black" stroke="black" points="260.687,-195.828 269.71,-190.275 259.193,-188.989 260.687,-195.828"/> +<text text-anchor="middle" x="234" y="-226.3" font-family="sans-serif" font-size="8.00">promotePixel</text> +</g> +<!-- PixelCMYK16->PixelRGB16 --> +<g id="edge32" class="edge"><title>PixelCMYK16->PixelRGB16</title> +<path fill="none" stroke="black" d="M564.03,-35.4654C568.707,-45.2873 571.707,-57.2873 565,-66 553.678,-80.7091 507.858,-90.6423 472.496,-96.2857"/> +<polygon fill="black" stroke="black" points="471.73,-92.862 462.373,-97.8319 472.787,-99.7817 471.73,-92.862"/> +<text text-anchor="middle" x="590" y="-58.3" font-family="sans-serif" font-size="8.00">convertPixel</text> +</g> +<!-- PixelCMYK8->PixelRGB8 --> +<g id="edge34" class="edge"><title>PixelCMYK8->PixelRGB8</title> +<path fill="none" stroke="black" d="M257.173,-372.299C258.645,-381.28 259.584,-392.241 258,-402 257.535,-404.865 256.875,-407.811 256.1,-410.724"/> +<polygon fill="black" stroke="black" points="252.737,-409.753 253.143,-420.34 259.427,-411.811 252.737,-409.753"/> +<text text-anchor="middle" x="280" y="-394.3" font-family="sans-serif" font-size="8.00">convertPixel</text> +</g> +<!-- PixelYCbCr8->PixelRGB8 --> +<g id="edge36" class="edge"><title>PixelYCbCr8->PixelRGB8</title> +<path fill="none" stroke="black" d="M149.836,-372.162C150.645,-381.97 153.174,-393.727 160,-402 171.431,-415.854 189.112,-424.462 205.475,-429.768"/> +<polygon fill="black" stroke="black" points="204.847,-433.23 215.426,-432.663 206.802,-426.509 204.847,-433.23"/> +<text text-anchor="middle" x="182" y="-394.3" font-family="sans-serif" font-size="8.00">convertPixel</text> +</g> +<!-- PixelYCbCr8->Pixel8 --> +<g id="edge54" class="edge"><title>PixelYCbCr8->Pixel8</title> +<path fill="none" stroke="black" d="M174.688,-340.875C202.411,-326.136 247.432,-302.201 277.376,-286.281"/> +<polygon fill="black" stroke="black" points="279.34,-289.201 286.527,-281.416 276.054,-283.02 279.34,-289.201"/> +<text text-anchor="middle" x="263" y="-310.3" font-family="sans-serif" font-size="8.00">computeLuma</text> +</g> +</g> +</svg>
src/Codec/Picture.hs view
@@ -260,7 +260,7 @@ readJpeg :: FilePath -> IO (Either String DynamicImage) readJpeg = withImageDecoder decodeJpeg --- | Try to load a .bmp file. The colorspace would be RGB or RGBA +-- | Try to load a .bmp file. The colorspace would be RGB or Y. readBitmap :: FilePath -> IO (Either String DynamicImage) readBitmap = withImageDecoder decodeBitmap
src/Codec/Picture/Bitmap.hs view
@@ -251,28 +251,51 @@ in inner readIndex writeIndex +decodeImageY8 :: BmpInfoHeader -> B.ByteString -> Image Pixel8 +decodeImageY8 (BmpInfoHeader { width = w, height = h }) str = Image wi hi stArray + where wi = fromIntegral w + hi = fromIntegral h + stArray = runST $ do + arr <- M.new (fromIntegral $ w * h * 1) + forM_ [hi - 1, hi - 2 .. 0] (readLine arr) + V.unsafeFreeze arr + stride = linePadding 8 wi + readLine arr line = + let readIndex = (wi * 1 + stride) * line + lastIndex = wi * (hi - 1 - line + 1) * 1 + writeIndex = wi * (hi - 1 - line) * 1 + + inner _ writeIdx | writeIdx >= lastIndex = return () + inner readIdx writeIdx = do + (arr `M.unsafeWrite` writeIdx) (str `B.index` readIdx) + inner (readIdx + 1) (writeIdx + 1) + + in inner readIndex writeIndex + -- | Try to decode a bitmap image. -- Right now this function can output the following pixel types : -- -- * PixelRGB8 -- +-- * Pixel8 +-- decodeBitmap :: B.ByteString -> Either String DynamicImage decodeBitmap str = flip runGetStrict str $ do hdr <- get :: Get BmpHeader bmpHeader <- get :: Get BmpInfoHeader + + readed <- bytesRead + when (readed > fromIntegral (dataOffset hdr)) + (fail "Invalid bmp image, data in header") + + skip . fromIntegral $ dataOffset hdr - fromIntegral readed + rest <- getRemainingBytes case (bitPerPixel bmpHeader, planes bmpHeader, bitmapCompression bmpHeader) of -- (32, 1, 0) -> {- ImageRGBA8 <$>-} fail "Meuh" - (24, 1, 0) -> do - readed <- bytesRead - - when (readed > fromIntegral (dataOffset hdr)) - (fail "Invalid bmp image, data in header") - - skip . fromIntegral $ dataOffset hdr - fromIntegral readed - rest <- getRemainingBytes - return . ImageRGB8 $ decodeImageRGB8 bmpHeader rest + (24, 1, 0) -> return . ImageRGB8 $ decodeImageRGB8 bmpHeader rest + ( 8, 1, 0) -> return . ImageY8 $ decodeImageY8 bmpHeader rest a -> fail $ "Can't handle BMP file " ++ show a
src/Codec/Picture/ConvGraph.hs view
@@ -6,4 +6,5 @@ -- -- * Arrows describe functions -- --- <<data:image/png;base64,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>> +-- <<docimages/pixelgraph.svg>> +--
src/Codec/Picture/Types.hs view
@@ -208,7 +208,8 @@ dropTransparency :: a -> b -- | access the transparency (alpha layer) of a given - -- transparent pixel type + -- transparent pixel type. + -- DEPRECATED, you should use `pixelOpacity` getTransparency :: a -> PixelBaseComponent a instance TransparentPixel PixelRGBA8 PixelRGB8 where @@ -322,7 +323,7 @@ | ImageCMYK16 (Image PixelCMYK16) -- | Helper function to help extract information from dynamic --- image. To get the width of an dynamic image, you can use +-- image. To get the width of a dynamic image, you can use -- the following snippet : -- -- > dynWidth :: DynamicImage -> Int @@ -348,7 +349,7 @@ -- You can perform pixel colorspace independant operations with this -- function. -- --- For instance, if you wan't to extract a square crop of any image, +-- For instance, if you want to extract a square crop of any image, -- without caring about colorspace, you can use the following snippet. -- -- > dynSquare :: DynamicImage -> DynamicImage @@ -391,17 +392,20 @@ rnf (ImageCMYK8 img) = rnf img rnf (ImageCMYK16 img) = rnf img --- | Simple alias for greyscale value in 8 bits. +-- | Type alias for 8bit greyscale pixels. For simplicity, +-- greyscale pixels use plain numbers instead of a separate type. type Pixel8 = Word8 --- | Simple alias for greyscale value in 16 bits. +-- | Type alias for 16bit greyscale pixels. type Pixel16 = Word16 --- | Simple alias for greyscale value in 16 bits. +-- | Type alias for 32bit greyscale pixels. type Pixel32 = Word32 --- | Floating greyscale value, the 0 to 255 8 bit range maps --- to 0 to 1 in this floating version +-- | Type alias for 32bit floating point greyscale pixels. The standard +-- bounded value range is mapped to the closed interval [0,1] i.e. +-- +-- > map promotePixel [0, 1 .. 255 :: Pixel8] == [0/255, 1/255 .. 1.0 :: PixelF] type PixelF = Float -- | Pixel type storing Luminance (Y) and alpha information @@ -457,7 +461,7 @@ deriving (Eq, Ord, Show) -- | Pixel type storing HDR pixel on 32 bits float --- Value are stored in the following order : +-- Values are stored in the following order : -- -- * Red -- @@ -471,7 +475,7 @@ deriving (Eq, Ord, Show) -- | Pixel storing data in the YCbCr colorspace, --- value are stored in the following order : +-- values are stored in the following order : -- -- * Y (luminance) -- @@ -484,7 +488,7 @@ {-# UNPACK #-} !Pixel8 -- Cb blue difference deriving (Eq, Ord, Show) --- | Pixel storing data in the CMYK colorspace. value +-- | Pixel storing data in the CMYK colorspace. Values -- are stored in the following order : -- -- * Cyan @@ -501,7 +505,7 @@ {-# UNPACK #-} !Pixel8 -- Black deriving (Eq, Ord, Show) --- | Pixel storing data in the CMYK colorspace. value +-- | Pixel storing data in the CMYK colorspace. Values -- are stored in the following order : -- -- * Cyan @@ -572,6 +576,12 @@ mixWith :: (Int -> PixelBaseComponent a -> PixelBaseComponent a -> PixelBaseComponent a) -> a -> a -> a + -- | Return the opacity of a pixel, if the pixel has an + -- alpha layer, return the alpha value. If the pixel + -- doesn't have an alpha value, return a value + -- representing the opaqueness. + pixelOpacity :: a -> PixelBaseComponent a + -- | Return the number of component of the pixel componentCount :: a -> Int @@ -615,13 +625,13 @@ unsafeWritePixel :: PrimMonad m => M.STVector (PrimState m) (PixelBaseComponent a) -> Int -> a -> m () --- | Implement upcasting for pixel types --- Minimal declaration declaration `promotePixel` --- It is strongly recommanded to overload promoteImage to keep +-- | Implement upcasting for pixel types. +-- Minimal declaration of `promotePixel`. +-- It is strongly recommended to overload promoteImage to keep -- performance acceptable class (Pixel a, Pixel b) => ColorConvertible a b where -- | Convert a pixel type to another pixel type. This - -- operation should never loss any data. + -- operation should never lose any data. promotePixel :: a -> b -- | Change the underlying pixel type of an image by performing a full copy @@ -642,8 +652,8 @@ convertImage = pixelMap convertPixel -- | Create an image given a function to generate pixels. --- The function will receive value from 0 to width-1 for the x parameter --- and 0 to height-1 for the y parameter. The coordinate 0,0 is the upper +-- The function will receive values from 0 to width-1 for the x parameter +-- and 0 to height-1 for the y parameter. The coordinates 0,0 are the upper -- left corner of the image, and (width-1, height-1) the lower right corner. -- -- for example, to create a small gradient image : @@ -672,8 +682,8 @@ V.unsafeFreeze arr -- | Create an image using a monadic initializer function. --- The function will receive value from 0 to width-1 for the x parameter --- and 0 to height-1 for the y parameter. The coordinate 0,0 is the upper +-- The function will receive values from 0 to width-1 for the x parameter +-- and 0 to height-1 for the y parameter. The coordinates 0,0 are the upper -- left corner of the image, and (width-1, height-1) the lower right corner. -- -- The function is called for each pixel in the line from left to right (0 to width - 1) @@ -698,8 +708,8 @@ unsafeFreezeImage mutImage -- | Create an image given a function to generate pixels. --- The function will receive value from 0 to width-1 for the x parameter --- and 0 to height-1 for the y parameter. The coordinate 0,0 is the upper +-- The function will receive values from 0 to width-1 for the x parameter +-- and 0 to height-1 for the y parameter. The coordinates 0,0 are the upper -- left corner of the image, and (width-1, height-1) the lower right corner. -- -- the acc parameter is a user defined one. @@ -922,6 +932,9 @@ instance Pixel Pixel8 where type PixelBaseComponent Pixel8 = Word8 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f = f 0 @@ -951,7 +964,7 @@ instance ColorConvertible Pixel8 Pixel16 where {-# INLINE promotePixel #-} - promotePixel c = fromIntegral c `unsafeShiftL` 8 + promotePixel c = fromIntegral c * 257 instance ColorConvertible Pixel8 PixelRGB8 where {-# INLINE promotePixel #-} @@ -967,6 +980,9 @@ instance Pixel Pixel16 where type PixelBaseComponent Pixel16 = Word16 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f = f 0 @@ -1004,6 +1020,9 @@ instance Pixel Pixel32 where type PixelBaseComponent Pixel32 = Word32 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f = f 0 @@ -1029,6 +1048,9 @@ instance Pixel PixelF where type PixelBaseComponent PixelF = Float + {-# INLINE pixelOpacity #-} + pixelOpacity = const 1.0 + {-# INLINE mixWith #-} mixWith f = f 0 @@ -1057,6 +1079,9 @@ instance Pixel PixelYA8 where type PixelBaseComponent PixelYA8 = Word8 + {-# INLINE pixelOpacity #-} + pixelOpacity (PixelYA8 _ a) = a + {-# INLINE mixWith #-} mixWith f (PixelYA8 ya aa) (PixelYA8 yb ab) = PixelYA8 (f 0 ya yb) (f 1 aa ab) @@ -1118,6 +1143,9 @@ instance Pixel PixelYA16 where type PixelBaseComponent PixelYA16 = Word16 + {-# INLINE pixelOpacity #-} + pixelOpacity (PixelYA16 _ a) = a + {-# INLINE mixWith #-} mixWith f (PixelYA16 ya aa) (PixelYA16 yb ab) = PixelYA16 (f 0 ya yb) (f 1 aa ab) @@ -1169,6 +1197,10 @@ instance Pixel PixelRGBF where type PixelBaseComponent PixelRGBF = PixelF + + {-# INLINE pixelOpacity #-} + pixelOpacity = const 1.0 + {-# INLINE mixWith #-} mixWith f (PixelRGBF ra ga ba) (PixelRGBF rb gb bb) = PixelRGBF (f 0 ra rb) (f 1 ga gb) (f 2 ba bb) @@ -1221,6 +1253,9 @@ instance Pixel PixelRGB16 where type PixelBaseComponent PixelRGB16 = Pixel16 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f (PixelRGB16 ra ga ba) (PixelRGB16 rb gb bb) = PixelRGB16 (f 0 ra rb) (f 1 ga gb) (f 2 ba bb) @@ -1286,6 +1321,9 @@ instance Pixel PixelRGB8 where type PixelBaseComponent PixelRGB8 = Word8 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f (PixelRGB8 ra ga ba) (PixelRGB8 rb gb bb) = PixelRGB8 (f 0 ra rb) (f 1 ga gb) (f 2 ba bb) @@ -1353,6 +1391,9 @@ instance Pixel PixelRGBA8 where type PixelBaseComponent PixelRGBA8 = Word8 + {-# INLINE pixelOpacity #-} + pixelOpacity (PixelRGBA8 _ _ _ a) = a + {-# INLINE mixWith #-} mixWith f (PixelRGBA8 ra ga ba aa) (PixelRGBA8 rb gb bb ab) = PixelRGBA8 (f 0 ra rb) (f 1 ga gb) (f 2 ba bb) (f 3 aa ab) @@ -1416,6 +1457,9 @@ instance Pixel PixelRGBA16 where type PixelBaseComponent PixelRGBA16 = Pixel16 + {-# INLINE pixelOpacity #-} + pixelOpacity (PixelRGBA16 _ _ _ a) = a + {-# INLINE mixWith #-} mixWith f (PixelRGBA16 ra ga ba aa) (PixelRGBA16 rb gb bb ab) = PixelRGBA16 (f 0 ra rb) (f 1 ga gb) (f 2 ba bb) (f 3 aa ab) @@ -1485,6 +1529,9 @@ instance Pixel PixelYCbCr8 where type PixelBaseComponent PixelYCbCr8 = Word8 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f (PixelYCbCr8 ya cba cra) (PixelYCbCr8 yb cbb crb) = PixelYCbCr8 (f 0 ya yb) (f 1 cba cbb) (f 2 cra crb) @@ -1643,6 +1690,9 @@ instance Pixel PixelCMYK8 where type PixelBaseComponent PixelCMYK8 = Word8 + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound + {-# INLINE mixWith #-} mixWith f (PixelCMYK8 ca ma ya ka) (PixelCMYK8 cb mb yb kb) = PixelCMYK8 (f 0 ca cb) (f 1 ma mb) (f 2 ya yb) (f 3 ka kb) @@ -1746,6 +1796,9 @@ -------------------------------------------------- instance Pixel PixelCMYK16 where type PixelBaseComponent PixelCMYK16 = Word16 + + {-# INLINE pixelOpacity #-} + pixelOpacity = const maxBound {-# INLINE mixWith #-} mixWith f (PixelCMYK16 ca ma ya ka) (PixelCMYK16 cb mb yb kb) =