29 #include "ksane_preview_thread.moc"
32 #include <QMutexLocker>
39 status(SANE_STATUS_GOOD),
49 m_invertColors(false),
50 m_readStatus(READ_READY),
52 m_saneStartDone(false),
62 m_invertColors = inverted;
74 m_saneStartDone =
false;
77 status = sane_start(m_saneHandle);
79 if (
status != SANE_STATUS_GOOD) {
80 kDebug() <<
"sane_start=" << sane_strstatus(
status);
81 sane_cancel(m_saneHandle);
87 status = sane_get_parameters(m_saneHandle, &m_params);
88 if (
status != SANE_STATUS_GOOD) {
89 kDebug() <<
"sane_get_parameters=" << sane_strstatus(
status);
90 sane_cancel(m_saneHandle);
96 m_frameSize = m_params.lines * m_params.bytes_per_line;
97 if ((m_params.format == SANE_FRAME_RED) ||
98 (m_params.format == SANE_FRAME_GREEN) ||
99 (m_params.format == SANE_FRAME_BLUE))
102 m_dataSize = m_frameSize*3;
105 m_dataSize = m_frameSize;
109 if ((m_img->height() != m_params.lines) ||
110 (m_img->width() != m_params.pixels_per_line))
113 if (m_params.lines > 0) {
114 *m_img = QImage(m_params.pixels_per_line, m_params.lines, QImage::Format_RGB32);
118 *m_img = QImage(m_params.pixels_per_line, m_params.pixels_per_line, QImage::Format_RGB32);
120 m_img->fill(0xFFFFFFFF);
122 m_imageResized =
false;
130 m_saneStartDone =
true;
141 if (m_dataSize <= 0)
return 0;
145 if (m_frameSize < m_dataSize) {
146 bytesRead = m_frameRead + (m_frameSize * m_frame_t_count);
149 bytesRead = m_frameRead;
152 return (
int)(((float)bytesRead * 100.0)/m_dataSize);
155 void KSanePreviewThread::readData()
162 case SANE_STATUS_GOOD:
166 case SANE_STATUS_EOF:
168 if (m_frameRead < m_frameSize) {
169 kDebug() <<
"frameRead =" << m_frameRead <<
", frameSize =" << m_frameSize;
173 if (m_params.last_frame == SANE_TRUE) {
180 SANE_Status
status = sane_start(m_saneHandle);
181 if (status != SANE_STATUS_GOOD) {
182 kDebug() <<
"sane_start =" << sane_strstatus(status);
186 status = sane_get_parameters(m_saneHandle, &m_params);
187 if (status != SANE_STATUS_GOOD) {
188 kDebug() <<
"sane_get_parameters =" << sane_strstatus(status);
190 sane_cancel(m_saneHandle);
202 kDebug() <<
"sane_read=" << status <<
"=" << sane_strstatus(status);
204 sane_cancel(m_saneHandle);
208 copyToPreviewImg(readBytes);
211 #define inc_pixel(x,y,ppl) { x++; if (x>=ppl) { y++; x=0;} }
212 #define inc_color_index(index) { index++; if (index==3) index=0;}
214 #define index_red8_to_argb8(i) (i*4 + 2)
215 #define index_red16_to_argb8(i) (i*2 + 2)
217 #define index_green8_to_argb8(i) (i*4 + 1)
218 #define index_green16_to_argb8(i) (i*2 + 1)
220 #define index_blue8_to_argb8(i) (i*4)
221 #define index_blue16_to_argb8(i) (i*2)
223 void KSanePreviewThread::copyToPreviewImg(
int read_bytes)
227 uchar *imgBits = m_img->bits();
228 if (m_invertColors) {
229 if (m_params.depth >= 8) {
230 for(
int i=0; i<read_bytes; i++) {
231 m_readData[i] = 255 - m_readData[i];
234 if (m_params.depth == 1) {
235 for(
int i=0; i<read_bytes; i++) {
236 m_readData[i] = ~m_readData[i];
240 switch (m_params.format)
242 case SANE_FRAME_GRAY:
243 if (m_params.depth == 1) {
245 for (i=0; i<read_bytes; i++) {
246 if (m_pixel_y >= m_img->height()) {
248 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
249 m_imageResized =
true;
251 for (j=7; j>=0; --j) {
252 if ((m_readData[i] & (1<<j)) == 0) {
253 m_img->setPixel(m_pixel_x,
258 m_img->setPixel(m_pixel_x,
263 if(m_pixel_x >= m_params.pixels_per_line) {
268 if (m_pixel_y >= m_params.lines)
break;
274 else if (m_params.depth == 8) {
275 for (
int i=0; i<read_bytes; i++) {
276 index = m_frameRead * 4;
277 if ((index + 2) >m_img->numBytes()) {
279 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
280 imgBits = m_img->bits();
281 m_imageResized =
true;
283 imgBits[index ] = m_readData[i];
284 imgBits[index + 1] = m_readData[i];
285 imgBits[index + 2] = m_readData[i];
290 else if (m_params.depth == 16) {
291 for (
int i=0; i<read_bytes; i++) {
292 if (m_frameRead%2 == 0) {
293 index = m_frameRead * 2;
294 if ((index + 2) > m_img->numBytes()) {
296 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
297 imgBits = m_img->bits();
298 m_imageResized =
true;
300 imgBits[index ] = m_readData[i+1];
301 imgBits[index + 1] = m_readData[i+1];
302 imgBits[index + 2] = m_readData[i+1];
311 if (m_params.depth == 8) {
312 for (
int i=0; i<read_bytes; i++) {
313 m_px_colors[m_px_c_index] = m_readData[i];
316 if (m_px_c_index == 0) {
317 if (m_pixel_y >= m_img->height()) {
319 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
320 m_imageResized =
true;
322 m_img->setPixel(m_pixel_x,
327 inc_pixel(m_pixel_x, m_pixel_y, m_params.pixels_per_line);
332 else if (m_params.depth == 16) {
333 for (
int i=0; i<read_bytes; i++) {
335 if (m_frameRead%2==0) {
336 m_px_colors[m_px_c_index] = m_readData[i];
338 if (m_px_c_index == 0) {
339 if (m_pixel_y >= m_img->height()) {
341 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
342 m_imageResized =
true;
344 m_img->setPixel(m_pixel_x,
349 inc_pixel(m_pixel_x, m_pixel_y, m_params.pixels_per_line);
358 if (m_params.depth == 8) {
359 for (
int i=0; i<read_bytes; i++) {
362 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
363 imgBits = m_img->bits();
364 m_imageResized =
true;
371 else if (m_params.depth == 16) {
372 for (
int i=0; i<read_bytes; i++) {
373 if (m_frameRead%2 == 0) {
376 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
377 imgBits = m_img->bits();
378 m_imageResized =
true;
388 case SANE_FRAME_GREEN:
389 if (m_params.depth == 8) {
390 for (
int i=0; i<read_bytes; i++) {
393 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
394 imgBits = m_img->bits();
395 m_imageResized =
true;
402 else if (m_params.depth == 16) {
403 for (
int i=0; i<read_bytes; i++) {
404 if (m_frameRead%2 == 0) {
407 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
408 imgBits = m_img->bits();
409 m_imageResized =
true;
419 case SANE_FRAME_BLUE:
420 if (m_params.depth == 8) {
421 for (
int i=0; i<read_bytes; i++) {
424 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
425 imgBits = m_img->bits();
426 m_imageResized =
true;
433 else if (m_params.depth == 16) {
434 for (
int i=0; i<read_bytes; i++) {
435 if (m_frameRead%2 == 0) {
438 *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
439 imgBits = m_img->bits();
440 m_imageResized =
true;
451 kWarning() <<
"Format" << m_params.format
452 <<
"and depth" << m_params.format
453 <<
"is not yet suppoeted by libksane!";
460 return m_saneStartDone;
465 if (m_imageResized) {
466 m_imageResized =
false;
#define index_blue8_to_argb8(i)
#define inc_color_index(index)
#define inc_pixel(x, y, ppl)
#define index_red16_to_argb8(i)
#define index_blue16_to_argb8(i)
KSanePreviewThread(SANE_Handle handle, QImage *img)
#define index_red8_to_argb8(i)
#define index_green8_to_argb8(i)
#define PREVIEW_READ_CHUNK_SIZE
void setPreviewInverted(bool)
#define index_green16_to_argb8(i)