1 /** 2 * Copyright: Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved 3 * Authors: $(Gabriel Gheorghe) 4 * License: $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007) 5 * Source 6 * Documentation: 7 * Coverage: 8 */ 9 module liberty.core.imaging.bitmap; 10 import std.string; 11 import derelict.freeimage.freeimage; 12 import liberty.core.imaging.image; 13 /// Image bitmap wrapper. 14 final class Bitmap { 15 private { 16 Image _lib; 17 FIBITMAP* _bitmap; 18 } 19 /// Load an image from file. 20 /// Throws: Image on error. 21 this(Image lib, string filename, int flags = 0) { 22 _lib = lib; 23 _bitmap = null; 24 const(char)* filenameZ = toStringz(filename); 25 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; 26 fif = FreeImage_GetFileType(filenameZ, 0); 27 if(fif == FIF_UNKNOWN) { 28 fif = FreeImage_GetFIFFromFilename(filenameZ); 29 } 30 if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { 31 _bitmap = FreeImage_Load(fif, filenameZ, flags); 32 } 33 if (_bitmap is null) 34 throw new ImageException(format("Coudln't load image %s", filename)); 35 } 36 /// Loads from existing bitmap handle. 37 /// Throws: Image on error. 38 this(Image lib, FIBITMAP* bitmap) { 39 _lib = lib; 40 if (bitmap is null) 41 throw new ImageException("Cannot make FIBitmap from null handle"); 42 _bitmap = bitmap; 43 } 44 /// Creates an image from from existing memory data. 45 /// Throws: Image on error. 46 this(Image lib, ubyte* data, int width, int height, int pitch, uint bpp, uint redMask, uint blueMask, uint greenMask, bool topDown = false) { 47 _lib = lib; 48 _bitmap = FreeImage_ConvertFromRawBits(data, width, height, pitch, bpp, redMask, greenMask, blueMask, FALSE); 49 if (_bitmap is null) 50 throw new ImageException("Cannot make FIBitmap from raw data"); 51 } 52 /// Releases the Image bitmap resource. 53 ~this() { 54 if (_bitmap !is null) { 55 debug import liberty.core.memory : ensureNotInGC; 56 debug ensureNotInGC("FIBitmap"); 57 FreeImage_Unload(_bitmap); 58 _bitmap = null; 59 } 60 } 61 /// Saves an image to a file. 62 /// Throws: Image on error. 63 void save(string filename, int flags = 0) { 64 const(char)* filenameZ = toStringz(filename); 65 FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(filenameZ); 66 if (fif == FIF_UNKNOWN) 67 throw new ImageException(format("Coudln't guess format for filename %s", filename)); 68 FreeImage_Save(fif, _bitmap, filenameZ, flags); 69 } 70 /// Returns: Width of the image. 71 uint width() { 72 return FreeImage_GetWidth(_bitmap); 73 } 74 /// Returns: Height of the image. 75 uint height() { 76 return FreeImage_GetHeight(_bitmap); 77 } 78 /// 79 FREE_IMAGE_TYPE imageType() { 80 return FreeImage_GetImageType(_bitmap); 81 } 82 /// 83 uint dotsPerMeterX() { 84 return FreeImage_GetDotsPerMeterX(_bitmap); 85 } 86 /// 87 uint dotsPerMeterY() { 88 return FreeImage_GetDotsPerMeterY(_bitmap); 89 } 90 /// 91 FREE_IMAGE_COLOR_TYPE colorType() { 92 return FreeImage_GetColorType(_bitmap); 93 } 94 /// Returns: Red channel bit mask. 95 uint redMask() { 96 return FreeImage_GetRedMask(_bitmap); 97 } 98 /// Returns: Green channel bit mask. 99 uint greenMask() { 100 return FreeImage_GetGreenMask(_bitmap); 101 } 102 /// Returns: Blue channel bit mask. 103 uint blueMask() { 104 return FreeImage_GetBlueMask(_bitmap); 105 } 106 /// Returns: Bits per pixels. 107 uint BPP() { 108 return FreeImage_GetBPP(_bitmap); 109 } 110 /// Returns: A pointer to pixels data. 111 void* data() { 112 return FreeImage_GetBits(_bitmap); 113 } 114 /// Returns: Pitch between scanlines in bytes. 115 uint pitch() { 116 return FreeImage_GetPitch(_bitmap); 117 } 118 /// Returns: A pointer to scanline y. 119 void* scanLine(int y) { 120 return FreeImage_GetScanLine(_bitmap, y); 121 } 122 /// Converts an image to 4-bits. 123 /// Returns: Converted image. 124 Bitmap convertTo4Bits() { 125 return new Bitmap(_lib, FreeImage_ConvertTo4Bits(_bitmap)); 126 } 127 /// Converts an image to 8-bits. 128 /// Returns: Converted image. 129 Bitmap convertTo8Bits() { 130 return new Bitmap(_lib, FreeImage_ConvertTo8Bits(_bitmap)); 131 } 132 /// Converts an image to greyscale. 133 /// Returns: Converted image. 134 Bitmap convertToGreyscale() { 135 return new Bitmap(_lib, FreeImage_ConvertToGreyscale(_bitmap)); 136 } 137 /// Converts an image to 16-bits 555. 138 /// Returns: Converted image. 139 Bitmap convertTo16Bits555() { 140 return new Bitmap(_lib, FreeImage_ConvertTo16Bits555(_bitmap)); 141 } 142 /// Converts an image to 16-bits 565. 143 /// Returns: Converted image. 144 Bitmap convertTo16Bits565() { 145 return new Bitmap(_lib, FreeImage_ConvertTo16Bits565(_bitmap)); 146 } 147 /// Converts an image to 24-bits. 148 /// Returns: Converted image. 149 Bitmap convertTo24Bits() { 150 return new Bitmap(_lib, FreeImage_ConvertTo24Bits(_bitmap)); 151 } 152 /// Converts an image to 32-bits. 153 /// Throws: ImageException on error. 154 /// Returns: Converted image. 155 Bitmap convertTo32Bits() { 156 return new Bitmap(_lib, FreeImage_ConvertTo32Bits(_bitmap)); 157 } 158 /// Converts an image to another format. 159 /// Throws: ImageException on error. 160 /// Returns: Converted image. 161 Bitmap convertToType(FREE_IMAGE_TYPE dstType, bool scaleLinear = true) { 162 FIBITMAP* converted = FreeImage_ConvertToType(_bitmap, dstType, scaleLinear); 163 if (converted is null) 164 throw new ImageException("disallowed conversion"); 165 return new Bitmap(_lib, converted); 166 } 167 /// Converts an image to float format. 168 /// Returns: Converted image. 169 Bitmap convertToFloat() { 170 return new Bitmap(_lib, FreeImage_ConvertToFloat(_bitmap)); 171 } 172 /// Converts an image to RGBF format. 173 /// Returns: Converted image. 174 Bitmap convertToRGBF() { 175 return new Bitmap(_lib, FreeImage_ConvertToRGBF(_bitmap)); 176 } 177 /// Converts an image to UINT16 format. 178 /// Returns: Converted image. 179 Bitmap convertToUINT16() { 180 return new Bitmap(_lib, FreeImage_ConvertToUINT16(_bitmap)); 181 } 182 /// Converts an image to RGB16 format. 183 /// Returns: Converted image. 184 Bitmap convertToRGB16() { 185 return new Bitmap(_lib, FreeImage_ConvertToRGB16(_bitmap)); 186 } 187 /// Clones an image. 188 /// Returns: Cloned image. 189 Bitmap clone() { 190 return new Bitmap(_lib, FreeImage_Clone(_bitmap)); 191 } 192 /// Applies color quantization. 193 Bitmap colorQuantize(FREE_IMAGE_QUANTIZE quantize) { 194 return new Bitmap(_lib, FreeImage_ColorQuantize(_bitmap, quantize)); 195 } 196 /// Applies tone-mapping operator. 197 Bitmap toneMapDrago03(double gamma = 2.2, double exposure = 0.0) { 198 return new Bitmap(_lib, FreeImage_TmoDrago03(_bitmap, gamma, exposure)); 199 } 200 /// Rescales the image. 201 Bitmap rescale(int dstWidth, int dstHeight, FREE_IMAGE_FILTER filter) { 202 return new Bitmap(_lib, FreeImage_Rescale(_bitmap, dstWidth, dstHeight, filter)); 203 } 204 /// Flips the image vertically. 205 /// Throws: ImageException on error. 206 void horizontalFlip() { 207 BOOL res = FreeImage_FlipHorizontal(_bitmap); 208 if (res == FALSE) 209 throw new ImageException("cannot flip image horizontally"); 210 } 211 /// Flips the image horizontally. 212 /// Throws: FreeImageException on error. 213 void verticalFlip() { 214 BOOL res = FreeImage_FlipVertical(_bitmap); 215 if (res == FALSE) 216 throw new ImageException("cannot flip image horizontally"); 217 } 218 /// Rotates the image. 219 /// Returns: Rotated image. 220 Bitmap rotate(double angle, void* bkColor = null) { 221 return new Bitmap(_lib, FreeImage_Rotate(_bitmap, angle, bkColor)); 222 } 223 /// 224 uint numberOfChannels() { 225 uint bytespp = FreeImage_GetLine(_bitmap) / FreeImage_GetWidth(_bitmap); 226 uint samples = bytespp / imageType.sizeof; 227 return samples; 228 } 229 }