176 lines
5.4 KiB
C++
176 lines
5.4 KiB
C++
#include "rebuild.h"
|
|
|
|
#include <huagao/hgscanner_error.h>
|
|
#include <sane/sane_ex.h>
|
|
#include <cis/cis_param.h>
|
|
|
|
|
|
|
|
|
|
static std::string device_opt_json[] = {
|
|
"{\"rebuild\":{\"cat\":\"imgp\",\"group\":\"advance\",\"title\":\"CIS\\u56fe\\u50cf\\u8fd8\\u539f\",\"desc\":\"\\u5c06\\u4eceCIS\\u8f93\\u51fa\\u7684\\u539f\\u59cb\\u6570\\u636e\\u6d41\\uff0c\\u8fd8\\u539f\\u4e3aBMP\\u56fe\\u7247\\uff0c\\u5e76\\u62c6\\u5206\\u6b63\\u53cd\\u9762\",\"type\":\"bool\",\"pos\":10,\"ui-pos\":1,\"auth\":100,\"size\":4,\"auto\":false,\"cur\":true,\"default\":true}}"
|
|
};
|
|
|
|
rebuild::rebuild(bool weaker) : image_processor("rebuild")
|
|
{
|
|
if(weaker)
|
|
return;
|
|
|
|
ADD_THIS_JSON();
|
|
}
|
|
rebuild::~rebuild()
|
|
{}
|
|
|
|
int rebuild::set_value(const char* name/*nullptr for all options*/, void* val/*nullptr for restore*/)
|
|
{
|
|
int ret = SCANNER_ERR_OK;
|
|
|
|
if(strcmp(name, SANE_OPT_NAME(CIS_REBUILD)) == 0)
|
|
enabled_ = *(bool*)val;
|
|
else
|
|
ret = SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
|
|
|
return ret;
|
|
}
|
|
void rebuild::enable(const char* name, bool able)
|
|
{
|
|
enabled_ = able;
|
|
}
|
|
|
|
image_processor* rebuild::copy_weaker(void)
|
|
{
|
|
rebuild *weaker = new rebuild(true);
|
|
|
|
weaker->pos_ = pos_;
|
|
weaker->enabled_ = enabled_;
|
|
|
|
return weaker;
|
|
}
|
|
int rebuild::process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out)
|
|
{
|
|
int ret = SCANNER_ERR_OK;
|
|
|
|
if(is_enable())
|
|
{
|
|
for(auto& v: in)
|
|
{
|
|
do_rebuild(&v.info, v.img.ptr(), out);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
out = std::move(in);
|
|
for(auto& v: out)
|
|
v.info.prc_stage = get_position();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGINFO>& out)
|
|
{
|
|
int secl = cis::get_sector_pixels(0, info->resolution_x, true),
|
|
linel = cis::get_line_stream_length(info->resolution_x, false),
|
|
size = info->height * info->width / 2;
|
|
PROCIMGINFO o;
|
|
chronograph watch;
|
|
|
|
o.info = *info;
|
|
if(info->pos.paper_side != PAPER_SIDE_BACK &&
|
|
info->pos.paper_side != PAPER_SIDE_FRONT)
|
|
linel *= 2;
|
|
|
|
o.info.prc_stage = get_position();
|
|
o.info.pos.paper_side = PAPER_SIDE_FRONT;
|
|
o.info.pos.paper_all = 2;
|
|
o.info.pos.ind_in_paper = 0;
|
|
out.push_back(o);
|
|
o.info.pos.paper_side = PAPER_SIDE_BACK;
|
|
o.info.pos.ind_in_paper = 1;
|
|
out.push_back(o);
|
|
|
|
if(info->width == linel) // gray
|
|
{
|
|
|
|
}
|
|
else // color
|
|
{
|
|
uint8_t *srcd = stream + info->width * (info->height - 1), // line reverse
|
|
*dstf = nullptr, // (uint8_t*)malloc(size),
|
|
*dstb = nullptr, // (uint8_t*)malloc(size),
|
|
*df = dstf, *db = dstb,
|
|
soff[] = {11, 10, 9, 2, 1, 0};
|
|
|
|
out[1].info.channels = out[0].info.channels = 3;
|
|
out[0].info.width /= out[0].info.channels * 2;
|
|
out[1].info.width /= out[1].info.channels * 2;
|
|
|
|
out[0].img.create(out[0].info.height, out[0].info.width, CV_8UC3);
|
|
out[1].img.create(out[1].info.height, out[1].info.width, CV_8UC3);
|
|
|
|
df = dstf = out[0].img.ptr();
|
|
db = dstb = out[1].img.ptr();
|
|
|
|
o.info.width = out[0].info.width;
|
|
o.info.channels = out[0].info.channels;
|
|
//*/
|
|
for(int h = 0; h < info->height; ++h)
|
|
{
|
|
for(int w = 0; w < o.info.width; ++w)
|
|
{
|
|
int s = w / secl;
|
|
*df++ = srcd[(soff[s] + 0) * secl + (w % secl)];
|
|
*df++ = srcd[(soff[s] + 6) * secl + (w % secl)];
|
|
*df++ = srcd[(soff[s] + 3) * secl + (w % secl)];
|
|
|
|
*db++ = srcd[info->width / 2 + (soff[s] + 6) * secl + (w % secl)];
|
|
*db++ = srcd[info->width / 2 + (soff[s] + 0) * secl + (w % secl)];
|
|
*db++ = srcd[info->width / 2 + (soff[s] + 3) * secl + (w % secl)];
|
|
}
|
|
srcd -= info->width;
|
|
}
|
|
/*/
|
|
uint64_t *srcl = (uint64_t*)srcd;
|
|
int width = info->width / sizeof(*srcl),
|
|
count = width * info->height,
|
|
secll = secl / sizeof(*srcl),
|
|
secpos[] = {5, 4, 3, 5, 4, 3, 5, 4, 3, 2, 1, 0, 2, 1, 0, 2, 1, 0},
|
|
rgbsf[] = {0, 2, 1},
|
|
rgbsb[] = {1, 2, 0},
|
|
*rgbx[] = {rgbsf, rgbsb};
|
|
uint8_t *dstbuf[] = {df, db};
|
|
for(int off = 0; off < count; ++off)
|
|
{
|
|
int pixel = off / (secll * CIS_SECTOR_COUNT * 6) * o.info.width,
|
|
sector = (off / secll) % (CIS_SECTOR_COUNT * 3),
|
|
lm = off % width,
|
|
ind = lm / (width / 2);
|
|
uint64_t val = *srcl++;
|
|
uint8_t *dst = dstbuf[ind], rgb = rgbx[ind][(sector / 3) % 3];
|
|
|
|
pixel += secpos[sector] * secl;
|
|
pixel += (off % secll) * 8;
|
|
|
|
if(ind && lm + 1 == width)
|
|
{
|
|
srcd -= info->width;
|
|
srcl = (uint64_t*)srcd;
|
|
}
|
|
|
|
dst += pixel * 3 + rgb;
|
|
dst[0 * 3] = val >> (0 * 8);
|
|
dst[1 * 3] = val >> (1 * 8);
|
|
dst[2 * 3] = val >> (2 * 8);
|
|
dst[3 * 3] = val >> (3 * 8);
|
|
dst[4 * 3] = val >> (4 * 8);
|
|
dst[5 * 3] = val >> (5 * 8);
|
|
dst[6 * 3] = val >> (6 * 8);
|
|
dst[7 * 3] = val >> (7 * 8);
|
|
}
|
|
/////*///////////////////////////
|
|
}
|
|
|
|
size = watch.elapse_ms();
|
|
out[0].info.prc_time = size;
|
|
out[1].info.prc_time = size;
|
|
} |