mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-04 22:09:55 +00:00
157 lines
4.4 KiB
C++
157 lines
4.4 KiB
C++
// Aseprite Document Library
|
|
// Copyright (c) 2001-2014 David Capello
|
|
//
|
|
// This file is released under the terms of the MIT license.
|
|
// Read LICENSE.txt for more information.
|
|
|
|
#ifndef DOC_IMAGE_BITS_H_INCLUDED
|
|
#define DOC_IMAGE_BITS_H_INCLUDED
|
|
#pragma once
|
|
|
|
#include "doc/image.h"
|
|
#include "doc/image_iterator.h"
|
|
|
|
namespace doc {
|
|
|
|
template<typename ImageTraits>
|
|
class ImageBits {
|
|
public:
|
|
typedef typename ImageTraits::address_t address_t;
|
|
typedef ImageIterator<ImageTraits> iterator;
|
|
typedef ImageConstIterator<ImageTraits> const_iterator;
|
|
|
|
ImageBits() :
|
|
m_image(NULL),
|
|
m_bounds(0, 0, 0, 0) {
|
|
}
|
|
|
|
ImageBits(const ImageBits& other) :
|
|
m_image(other.m_image),
|
|
m_bounds(other.m_bounds) {
|
|
}
|
|
|
|
ImageBits(Image* image, const gfx::Rect& bounds) :
|
|
m_image(image),
|
|
m_bounds(bounds) {
|
|
ASSERT(bounds.x >= 0 && bounds.x+bounds.w <= image->width() &&
|
|
bounds.y >= 0 && bounds.y+bounds.h <= image->height());
|
|
}
|
|
|
|
ImageBits& operator=(const ImageBits& other) {
|
|
m_image = other.m_image;
|
|
m_bounds = other.m_bounds;
|
|
return *this;
|
|
}
|
|
|
|
// Iterate over the full area.
|
|
iterator begin() {
|
|
return iterator(m_image, m_bounds, m_bounds.x, m_bounds.y);
|
|
}
|
|
iterator end() {
|
|
iterator it(m_image, m_bounds, m_bounds.x+m_bounds.w-1, m_bounds.y+m_bounds.h-1);
|
|
++it;
|
|
return it;
|
|
}
|
|
|
|
const_iterator begin() const {
|
|
return const_iterator(m_image, m_bounds, m_bounds.x, m_bounds.y);
|
|
}
|
|
const_iterator end() const {
|
|
const_iterator it(m_image, m_bounds, m_bounds.x+m_bounds.w-1, m_bounds.y+m_bounds.h-1);
|
|
++it;
|
|
return it;
|
|
}
|
|
|
|
// Iterate over a sub-area.
|
|
iterator begin_area(const gfx::Rect& area) {
|
|
ASSERT(m_bounds.contains(area));
|
|
return iterator(m_image, area, area.x, area.y);
|
|
}
|
|
iterator end_area(const gfx::Rect& area) {
|
|
ASSERT(m_bounds.contains(area));
|
|
iterator it(m_image, area, area.x+area.w-1, area.y+area.h-1);
|
|
++it;
|
|
return it;
|
|
}
|
|
|
|
const_iterator begin_area(const gfx::Rect& area) const {
|
|
ASSERT(m_bounds.contains(area));
|
|
return const_iterator(m_image, area, area.x, area.y);
|
|
}
|
|
const_iterator end_area(const gfx::Rect& area) const {
|
|
ASSERT(m_bounds.contains(area));
|
|
const_iterator it(m_image, area, area.x+area.w-1, area.y+area.h-1);
|
|
++it;
|
|
return it;
|
|
}
|
|
|
|
Image* image() const { return m_image; }
|
|
const gfx::Rect& bounds() { return m_bounds; }
|
|
|
|
Image* image() { return m_image; }
|
|
|
|
void unlock() {
|
|
if (m_image) {
|
|
m_image->unlockBits(*this);
|
|
m_image = NULL;
|
|
}
|
|
}
|
|
|
|
private:
|
|
Image* m_image;
|
|
gfx::Rect m_bounds;
|
|
};
|
|
|
|
template<typename ImageTraits>
|
|
class LockImageBits {
|
|
public:
|
|
typedef ImageBits<ImageTraits> Bits;
|
|
typedef typename Bits::iterator iterator;
|
|
typedef typename Bits::const_iterator const_iterator;
|
|
|
|
explicit LockImageBits(const Image* image)
|
|
: m_bits(image->lockBits<ImageTraits>(Image::ReadLock, image->bounds())) {
|
|
}
|
|
|
|
LockImageBits(const Image* image, const gfx::Rect& bounds)
|
|
: m_bits(image->lockBits<ImageTraits>(Image::ReadLock, bounds)) {
|
|
}
|
|
|
|
LockImageBits(Image* image, Image::LockType lockType)
|
|
: m_bits(image->lockBits<ImageTraits>(lockType, image->bounds())) {
|
|
}
|
|
|
|
LockImageBits(Image* image, Image::LockType lockType, const gfx::Rect& bounds)
|
|
: m_bits(image->lockBits<ImageTraits>(lockType, bounds)) {
|
|
}
|
|
|
|
~LockImageBits() {
|
|
m_bits.image()->unlockBits(m_bits);
|
|
}
|
|
|
|
// Iterators.
|
|
iterator begin() { return m_bits.begin(); }
|
|
iterator end() { return m_bits.end(); }
|
|
const_iterator begin() const { return m_bits.begin(); }
|
|
const_iterator end() const { return m_bits.end(); }
|
|
|
|
iterator begin_area(const gfx::Rect& area) { return m_bits.begin_area(area); }
|
|
iterator end_area(const gfx::Rect& area) { return m_bits.end_area(area); }
|
|
const_iterator begin_area(const gfx::Rect& area) const { return m_bits.begin_area(area); }
|
|
const_iterator end_area(const gfx::Rect& area) const { return m_bits.end_area(area); }
|
|
|
|
const Image* image() const { return m_bits.image(); }
|
|
const gfx::Rect& bounds() const { return m_bits.bounds(); }
|
|
|
|
Image* image() { return m_bits.image(); }
|
|
|
|
private:
|
|
Bits m_bits;
|
|
|
|
LockImageBits(); // Undefined
|
|
};
|
|
|
|
} // namespace doc
|
|
|
|
#endif
|