code_twain/sane/scanned_img.cpp

144 lines
3.1 KiB
C++
Raw Normal View History

2022-06-15 03:04:40 +00:00
#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_;
}