2014-10-21 09:21:31 +08:00
|
|
|
// Aseprite Document Library
|
2024-12-24 02:55:43 +08:00
|
|
|
// Copyright (c) 2018-2024 Igara Studio S.A.
|
2016-05-14 04:08:07 +08:00
|
|
|
// Copyright (c) 2001-2016 David Capello
|
2014-10-21 09:21:31 +08:00
|
|
|
//
|
|
|
|
// This file is released under the terms of the MIT license.
|
|
|
|
// Read LICENSE.txt for more information.
|
|
|
|
|
|
|
|
#ifndef DOC_IMAGE_H_INCLUDED
|
|
|
|
#define DOC_IMAGE_H_INCLUDED
|
2014-03-30 06:40:17 +08:00
|
|
|
#pragma once
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2014-10-21 09:21:31 +08:00
|
|
|
#include "doc/color.h"
|
2016-05-14 04:08:07 +08:00
|
|
|
#include "doc/color_mode.h"
|
2014-10-21 09:21:31 +08:00
|
|
|
#include "doc/image_buffer.h"
|
2024-12-24 02:55:43 +08:00
|
|
|
#include "doc/image_iterators2.h"
|
2016-05-14 04:08:07 +08:00
|
|
|
#include "doc/image_spec.h"
|
2014-10-21 09:21:31 +08:00
|
|
|
#include "doc/object.h"
|
|
|
|
#include "doc/pixel_format.h"
|
2014-12-28 22:06:11 +08:00
|
|
|
#include "gfx/clip.h"
|
|
|
|
#include "gfx/rect.h"
|
|
|
|
#include "gfx/size.h"
|
2012-02-13 10:21:06 +08:00
|
|
|
|
2014-10-21 09:21:31 +08:00
|
|
|
namespace doc {
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
template<typename ImageTraits>
|
|
|
|
class ImageBits;
|
2016-05-14 04:08:07 +08:00
|
|
|
class Palette;
|
2020-08-28 07:32:22 +08:00
|
|
|
class Pen;
|
|
|
|
class RgbMap;
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
class Image : public Object {
|
2024-12-17 01:52:19 +08:00
|
|
|
public:
|
2013-11-10 06:59:05 +08:00
|
|
|
enum LockType {
|
|
|
|
ReadLock, // Read-only lock
|
2014-10-21 09:21:31 +08:00
|
|
|
WriteLock, // Write-only lock
|
2023-08-08 02:12:11 +08:00
|
|
|
ReadWriteLock // Read and write
|
2013-08-06 08:20:19 +08:00
|
|
|
};
|
|
|
|
|
2013-11-11 00:26:48 +08:00
|
|
|
static Image* create(PixelFormat format,
|
|
|
|
int width,
|
|
|
|
int height,
|
|
|
|
const ImageBufferPtr& buffer = ImageBufferPtr());
|
|
|
|
static Image* create(const ImageSpec& spec, const ImageBufferPtr& buffer = ImageBufferPtr());
|
|
|
|
static Image* createCopy(const Image* image, const ImageBufferPtr& buffer = ImageBufferPtr());
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
virtual ~Image();
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2016-05-14 04:08:07 +08:00
|
|
|
const ImageSpec& spec() const { return m_spec; }
|
|
|
|
ColorMode colorMode() const { return m_spec.colorMode(); }
|
|
|
|
PixelFormat pixelFormat() const { return (PixelFormat)colorMode(); }
|
2020-08-28 07:32:22 +08:00
|
|
|
bool isTilemap() const { return m_spec.colorMode() == ColorMode::TILEMAP; }
|
2016-05-14 04:08:07 +08:00
|
|
|
int width() const { return m_spec.width(); }
|
|
|
|
int height() const { return m_spec.height(); }
|
|
|
|
gfx::Size size() const { return m_spec.size(); }
|
|
|
|
gfx::Rect bounds() const { return m_spec.bounds(); }
|
|
|
|
color_t maskColor() const { return m_spec.maskColor(); }
|
|
|
|
void setMaskColor(color_t c) { m_spec.setMaskColor(c); }
|
2020-07-08 06:06:48 +08:00
|
|
|
void setColorSpace(const gfx::ColorSpaceRef& cs) { m_spec.setColorSpace(cs); }
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2023-08-08 02:12:11 +08:00
|
|
|
// Number of bytes to store one pixel of this image.
|
|
|
|
int bytesPerPixel() const { return m_spec.bytesPerPixel(); }
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2023-08-08 02:12:11 +08:00
|
|
|
// Number of bytes to store all visible pixels on each row.
|
|
|
|
int widthBytes() const { return m_spec.widthBytes(); }
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2023-08-08 02:12:11 +08:00
|
|
|
// Number of bytes for each row of this image on memory (some
|
|
|
|
// bytes for each row might be hidden/just for alignment to
|
|
|
|
// "base_alignment").
|
|
|
|
int rowBytes() const { return m_rowBytes; }
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2023-08-08 02:12:11 +08:00
|
|
|
// Number of pixels for each row (some of these pixels are hidden
|
|
|
|
// when width() < rowPixels()).
|
|
|
|
int rowPixels() const { return m_rowBytes / bytesPerPixel(); }
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2014-11-17 08:32:18 +08:00
|
|
|
virtual int getMemSize() const override;
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
template<typename ImageTraits>
|
|
|
|
ImageBits<ImageTraits> lockBits(LockType lockType, const gfx::Rect& bounds)
|
2024-12-17 01:52:19 +08:00
|
|
|
{
|
2013-11-10 06:59:05 +08:00
|
|
|
return ImageBits<ImageTraits>(this, bounds);
|
2024-12-17 01:52:19 +08:00
|
|
|
}
|
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
template<typename ImageTraits>
|
|
|
|
ImageBits<ImageTraits> lockBits(LockType lockType, const gfx::Rect& bounds) const
|
2024-12-17 01:52:19 +08:00
|
|
|
{
|
2013-11-10 06:59:05 +08:00
|
|
|
return ImageBits<ImageTraits>(const_cast<Image*>(this), bounds);
|
2024-12-17 01:52:19 +08:00
|
|
|
}
|
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
template<typename ImageTraits>
|
|
|
|
void unlockBits(ImageBits<ImageTraits>& imageBits)
|
2024-12-17 01:52:19 +08:00
|
|
|
{
|
2013-11-10 06:59:05 +08:00
|
|
|
// Do nothing
|
2024-12-17 01:52:19 +08:00
|
|
|
}
|
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
// Warning: These functions doesn't have (and shouldn't have)
|
2014-10-21 09:21:31 +08:00
|
|
|
// bounds checks. Use the primitives defined in doc/primitives.h
|
2013-11-10 06:59:05 +08:00
|
|
|
// in case that you need bounds check.
|
|
|
|
virtual uint8_t* getPixelAddress(int x, int y) const = 0;
|
|
|
|
virtual color_t getPixel(int x, int y) const = 0;
|
|
|
|
virtual void putPixel(int x, int y, color_t color) = 0;
|
|
|
|
virtual void clear(color_t color) = 0;
|
2014-12-28 22:06:11 +08:00
|
|
|
virtual void copy(const Image* src, gfx::Clip area) = 0;
|
2013-11-10 06:59:05 +08:00
|
|
|
virtual void drawHLine(int x1, int y, int x2, color_t color) = 0;
|
|
|
|
virtual void fillRect(int x1, int y1, int x2, int y2, color_t color) = 0;
|
|
|
|
virtual void blendRect(int x1, int y1, int x2, int y2, color_t color, int opacity) = 0;
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2024-12-24 02:55:43 +08:00
|
|
|
ReadIterator readArea() const { return ReadIterator(this, this->bounds()); }
|
|
|
|
WriteIterator writeArea() { return WriteIterator(this, this->bounds()); }
|
|
|
|
|
|
|
|
ReadIterator readArea(const gfx::Rect& bounds,
|
|
|
|
const IteratorStart start = IteratorStart::TopLeft) const
|
|
|
|
{
|
|
|
|
return ReadIterator(this, bounds, start);
|
|
|
|
}
|
|
|
|
|
|
|
|
WriteIterator writeArea(const gfx::Rect& bounds,
|
|
|
|
const IteratorStart start = IteratorStart::TopLeft)
|
|
|
|
{
|
|
|
|
return WriteIterator(this, bounds, start);
|
|
|
|
}
|
|
|
|
|
2013-11-10 06:59:05 +08:00
|
|
|
protected:
|
2018-11-14 08:38:03 +08:00
|
|
|
Image(const ImageSpec& spec);
|
2024-12-17 01:52:19 +08:00
|
|
|
|
2023-08-08 02:12:11 +08:00
|
|
|
// Number of bytes for each row.
|
|
|
|
size_t m_rowBytes;
|
2024-12-17 01:52:19 +08:00
|
|
|
|
|
|
|
private:
|
2016-05-14 04:08:07 +08:00
|
|
|
ImageSpec m_spec;
|
2024-12-17 01:52:19 +08:00
|
|
|
};
|
|
|
|
|
2014-10-21 09:21:31 +08:00
|
|
|
} // namespace doc
|
2013-08-06 08:20:19 +08:00
|
|
|
|
2024-12-19 20:36:27 +08:00
|
|
|
#include "doc/image_bits.h"
|
|
|
|
#include "doc/image_iterator.h"
|
|
|
|
|
2009-08-18 05:38:00 +08:00
|
|
|
#endif
|