1 module gfm.image;
2 
3 public import gfm.image.stb_truetype;
4 
5 import imageformats;
6 import ae.utils.graphics.image;
7 import ae.utils.graphics.color;
8 
9 /// The one function you probably want to use.
10 /// Loads an image from a static array.
11 /// Might throw internally.
12 /// Throws: $(D ImageIOException) on error.
13 Image!RGBA loadImage(in void[] imageData)
14 {
15     IFImage ifImage = read_image_from_mem(cast(const(ubyte[])) imageData, 4);
16     int width = cast(int)ifImage.w;
17     int height = cast(int)ifImage.h;
18 
19     Image!RGBA loaded;
20     loaded.size(width, height);
21     loaded.pixels = cast(RGBA[]) ifImage.pixels; // no pixel copy, GC does the job
22     return loaded;
23 }
24 
25 /// Loads two different images:
26 /// - the first the 2nd is interpreted as greyscale 
27 /// and fetch in the alpha channel of the result.
28 Image!RGBA loadImageSeparateAlpha(in void[] imageDataRGB, in void[] imageDataAlpha)
29 {
30     IFImage ifImageRGB = read_image_from_mem(cast(const(ubyte[])) imageDataRGB, 3);
31     int widthRGB = cast(int)ifImageRGB.w;
32     int heightRGB = cast(int)ifImageRGB.h;
33 
34     IFImage ifImageA = read_image_from_mem(cast(const(ubyte[])) imageDataAlpha, 1);
35     int widthA = cast(int)ifImageA.w;
36     int heightA = cast(int)ifImageA.h;
37 
38     if ( (widthA != widthRGB) || (heightRGB != heightA) )
39     {
40         throw new ImageIOException("Image size mismatch");
41     }
42 
43     int width = widthA;
44     int height = heightA;
45 
46     Image!RGBA loaded;
47     loaded.size(width, height);
48 
49     for (int j = 0; j < height; ++j)
50     {
51         RGB* rgbscan = cast(RGB*)(&ifImageRGB.pixels[3 * (j * width)]);
52         ubyte* ascan = &ifImageA.pixels[j * width];
53         RGBA[] outscan = loaded.scanline(j);
54         for (int i = 0; i < width; ++i)
55         {
56             RGB rgb = rgbscan[i];
57             outscan[i] = RGBA(rgb.r, rgb.g, rgb.b, ascan[i]);
58         }
59     }
60     return loaded;
61 }
62 
63