144 lines
3.1 KiB
C++
144 lines
3.1 KiB
C++
|
#include "scanned_img.h"
|
|||
|
|
|||
|
#include <Windows.h>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
// class refer
|
|||
|
refer::refer() : ref_(1)
|
|||
|
{}
|
|||
|
refer::~refer()
|
|||
|
{}
|
|||
|
|
|||
|
COM_API_IMPLEMENT(refer, long, add_ref(void))
|
|||
|
{
|
|||
|
return InterlockedIncrement(&ref_);
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(refer, long, release(void))
|
|||
|
{
|
|||
|
long ref = InterlockedDecrement(&ref_);
|
|||
|
|
|||
|
if (ref == 0)
|
|||
|
delete this;
|
|||
|
|
|||
|
return ref;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
// class scanned_img
|
|||
|
scanned_img::scanned_img(SANE_Parameters head, unsigned char* data) : head_(head)
|
|||
|
{
|
|||
|
size_t bytes = line_bytes() * height();
|
|||
|
std::string h(file_header(SANE_IMAGE_TYPE_BMP, 200.0f));
|
|||
|
unsigned char* src = data + head.bytes_per_line * head.lines - head.bytes_per_line,
|
|||
|
* dst = NULL;
|
|||
|
|
|||
|
bytes_ = bytes + h.length();
|
|||
|
data_ = new unsigned char[bytes_];
|
|||
|
memcpy(data_, h.c_str(), h.length());
|
|||
|
dst = data_ + h.length();
|
|||
|
|
|||
|
if (head.format == SANE_FRAME_RGB)
|
|||
|
{
|
|||
|
for (int i = 0; i < height(); ++i)
|
|||
|
{
|
|||
|
for (int j = 0; j < head.pixels_per_line; ++j)
|
|||
|
{
|
|||
|
dst[j * 3 + 0] = src[j * 3 + 2];
|
|||
|
dst[j * 3 + 1] = src[j * 3 + 1];
|
|||
|
dst[j * 3 + 2] = src[j * 3 + 0];
|
|||
|
}
|
|||
|
src -= head.bytes_per_line;
|
|||
|
dst += line_bytes();
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
for (int i = 0; i < height(); ++i, dst += line_bytes(), src -= head.bytes_per_line)
|
|||
|
memcpy(dst, src, head.bytes_per_line);
|
|||
|
}
|
|||
|
}
|
|||
|
scanned_img::~scanned_img()
|
|||
|
{
|
|||
|
if (data_)
|
|||
|
delete[] data_;
|
|||
|
}
|
|||
|
|
|||
|
std::string scanned_img::file_header(SANE_ImageType type, float resolution)
|
|||
|
{
|
|||
|
std::string h("");
|
|||
|
|
|||
|
if (type == SANE_IMAGE_TYPE_BMP)
|
|||
|
{
|
|||
|
BITMAPINFOHEADER bih = { 0 };
|
|||
|
|
|||
|
bih.biSize = sizeof(bih);
|
|||
|
bih.biWidth = width();
|
|||
|
bih.biBitCount = depth();
|
|||
|
bih.biSizeImage = line_bytes() * height();
|
|||
|
bih.biPlanes = 1;
|
|||
|
bih.biHeight = height();
|
|||
|
bih.biCompression = BI_RGB;
|
|||
|
bih.biXPelsPerMeter = bih.biYPelsPerMeter = resolution * 39.37f + .5f;
|
|||
|
|
|||
|
h = std::string((char*)&bih, sizeof(bih));
|
|||
|
}
|
|||
|
|
|||
|
return h;
|
|||
|
}
|
|||
|
|
|||
|
// IRef
|
|||
|
COM_API_IMPLEMENT(scanned_img, long, add_ref(void))
|
|||
|
{
|
|||
|
return refer::add_ref();
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, long, release(void))
|
|||
|
{
|
|||
|
return refer::release();
|
|||
|
}
|
|||
|
|
|||
|
// IScanImg
|
|||
|
COM_API_IMPLEMENT(scanned_img, int, width(void))
|
|||
|
{
|
|||
|
return head_.pixels_per_line;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, int, line_bytes(void))
|
|||
|
{
|
|||
|
return (head_.bytes_per_line + 3) / 4 * 4;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, int, height(void))
|
|||
|
{
|
|||
|
return head_.lines;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, int, depth(void))
|
|||
|
{
|
|||
|
if (head_.format == SANE_FRAME_RGB)
|
|||
|
return head_.depth * 3;
|
|||
|
else
|
|||
|
return head_.depth;
|
|||
|
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, int, channel(void))
|
|||
|
{
|
|||
|
return head_.format == SANE_FRAME_RGB ? 3 : 1;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, SANE_Frame, type(void))
|
|||
|
{
|
|||
|
return head_.format;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, unsigned int, bytes(void))
|
|||
|
{
|
|||
|
return bytes_;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, unsigned char*, bits(void))
|
|||
|
{
|
|||
|
return data_;
|
|||
|
}
|
|||
|
COM_API_IMPLEMENT(scanned_img, void, copy_header(SANE_Parameters* head))
|
|||
|
{
|
|||
|
*head = head_;
|
|||
|
}
|