1// Aseprite Document Library
2// Copyright (c) 2018-2020 Igara Studio S.A.
3// Copyright (c) 2001-2016 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef DOC_IMAGE_H_INCLUDED
9#define DOC_IMAGE_H_INCLUDED
10#pragma once
11
12#include "doc/color.h"
13#include "doc/color_mode.h"
14#include "doc/image_buffer.h"
15#include "doc/image_spec.h"
16#include "doc/object.h"
17#include "doc/pixel_format.h"
18#include "gfx/clip.h"
19#include "gfx/rect.h"
20#include "gfx/size.h"
21
22namespace doc {
23
24 template<typename ImageTraits> class ImageBits;
25 class Palette;
26 class Pen;
27 class RgbMap;
28
29 class Image : public Object {
30 public:
31 enum LockType {
32 ReadLock, // Read-only lock
33 WriteLock, // Write-only lock
34 ReadWriteLock // Read and write
35 };
36
37 static Image* create(PixelFormat format, int width, int height,
38 const ImageBufferPtr& buffer = ImageBufferPtr());
39 static Image* create(const ImageSpec& spec,
40 const ImageBufferPtr& buffer = ImageBufferPtr());
41 static Image* createCopy(const Image* image,
42 const ImageBufferPtr& buffer = ImageBufferPtr());
43
44 virtual ~Image();
45
46 const ImageSpec& spec() const { return m_spec; }
47 ColorMode colorMode() const { return m_spec.colorMode(); }
48 PixelFormat pixelFormat() const { return (PixelFormat)colorMode(); }
49 bool isTilemap() const { return m_spec.colorMode() == ColorMode::TILEMAP; }
50 int width() const { return m_spec.width(); }
51 int height() const { return m_spec.height(); }
52 gfx::Size size() const { return m_spec.size(); }
53 gfx::Rect bounds() const { return m_spec.bounds(); }
54 color_t maskColor() const { return m_spec.maskColor(); }
55 void setMaskColor(color_t c) { m_spec.setMaskColor(c); }
56 void setColorSpace(const gfx::ColorSpaceRef& cs) { m_spec.setColorSpace(cs); }
57
58 virtual int getMemSize() const override;
59 int getRowStrideSize() const;
60 int getRowStrideSize(int pixels_per_row) const;
61
62 template<typename ImageTraits>
63 ImageBits<ImageTraits> lockBits(LockType lockType, const gfx::Rect& bounds) {
64 return ImageBits<ImageTraits>(this, bounds);
65 }
66
67 template<typename ImageTraits>
68 ImageBits<ImageTraits> lockBits(LockType lockType, const gfx::Rect& bounds) const {
69 return ImageBits<ImageTraits>(const_cast<Image*>(this), bounds);
70 }
71
72 template<typename ImageTraits>
73 void unlockBits(ImageBits<ImageTraits>& imageBits) {
74 // Do nothing
75 }
76
77 // Warning: These functions doesn't have (and shouldn't have)
78 // bounds checks. Use the primitives defined in doc/primitives.h
79 // in case that you need bounds check.
80 virtual uint8_t* getPixelAddress(int x, int y) const = 0;
81 virtual color_t getPixel(int x, int y) const = 0;
82 virtual void putPixel(int x, int y, color_t color) = 0;
83 virtual void clear(color_t color) = 0;
84 virtual void copy(const Image* src, gfx::Clip area) = 0;
85 virtual void drawHLine(int x1, int y, int x2, color_t color) = 0;
86 virtual void fillRect(int x1, int y1, int x2, int y2, color_t color) = 0;
87 virtual void blendRect(int x1, int y1, int x2, int y2, color_t color, int opacity) = 0;
88
89 protected:
90 Image(const ImageSpec& spec);
91
92 private:
93 ImageSpec m_spec;
94 };
95
96} // namespace doc
97
98// It's here because it needs a complete definition of Image class,
99// and then ImageTraits are used in the next functions below.
100#include "doc/image_traits.h"
101
102namespace doc {
103
104 inline int calculate_rowstride_bytes(PixelFormat pixelFormat, int pixels_per_row)
105 {
106 switch (pixelFormat) {
107 case IMAGE_RGB: return RgbTraits::getRowStrideBytes(pixels_per_row);
108 case IMAGE_GRAYSCALE: return GrayscaleTraits::getRowStrideBytes(pixels_per_row);
109 case IMAGE_INDEXED: return IndexedTraits::getRowStrideBytes(pixels_per_row);
110 case IMAGE_BITMAP: return BitmapTraits::getRowStrideBytes(pixels_per_row);
111 case IMAGE_TILEMAP: return TilemapTraits::getRowStrideBytes(pixels_per_row);
112 }
113 return 0;
114 }
115
116} // namespace doc
117
118#endif
119