diff --git a/src/ksanepreviewimagebuilder.cpp b/src/ksanepreviewimagebuilder.cpp index 000883c..eb423fe 100644 --- a/src/ksanepreviewimagebuilder.cpp +++ b/src/ksanepreviewimagebuilder.cpp @@ -1,311 +1,296 @@ /* ============================================================ * * This file is part of the KDE project * * Description : Sane interface for KDE * * Copyright (C) 2009 by Kare Sars * Copyright (C) 2018 by Alexander Volkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see . * * ============================================================ */ #include "ksanepreviewimagebuilder.h" #include #include namespace KSaneIface { KSanePreviewImageBuilder::KSanePreviewImageBuilder(QImage *img) : m_frameRead(0), m_pixel_x(0), m_pixel_y(0), m_px_c_index(0), m_img(img), m_imageResized(false) { m_px_colors[0] = 0; m_px_colors[1] = 0; m_px_colors[2] = 0; } void KSanePreviewImageBuilder::start(const SANE_Parameters ¶ms) { beginFrame(params); // create a new image if necessary if ((m_img->height() != m_params.lines) || (m_img->width() != m_params.pixels_per_line)) { // just hope that the frame size is not changed between different frames of the same image. if (m_params.lines > 0) { *m_img = QImage(m_params.pixels_per_line, m_params.lines, QImage::Format_RGB32); } else { // handscanners have the number of lines -1 -> make room for something *m_img = QImage(m_params.pixels_per_line, m_params.pixels_per_line, QImage::Format_RGB32); } m_img->fill(0xFFFFFFFF); } m_imageResized = false; } void KSanePreviewImageBuilder::beginFrame(const SANE_Parameters ¶ms) { m_params = params; m_frameRead = 0; m_pixel_x = 0; m_pixel_y = 0; m_px_c_index = 0; } #define inc_pixel(x,y,ppl) { x++; if (x>=ppl) { y++; x=0;} } #define inc_color_index(index) { index++; if (index==3) index=0;} #define index_red8_to_argb8(i) (i*4 + 2) #define index_red16_to_argb8(i) (i*2 + 2) #define index_green8_to_argb8(i) (i*4 + 1) #define index_green16_to_argb8(i) (i*2 + 1) #define index_blue8_to_argb8(i) (i*4) #define index_blue16_to_argb8(i) (i*2) bool KSanePreviewImageBuilder::copyToImage(const SANE_Byte readData[], int read_bytes) { int index; uchar *imgBits = m_img->bits(); switch (m_params.format) { case SANE_FRAME_GRAY: if (m_params.depth == 1) { int i, j; for (i = 0; i < read_bytes; i++) { if (m_pixel_y >= m_img->height()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); - m_imageResized = true; + renewImage(); } for (j = 7; j >= 0; --j) { if ((readData[i] & (1 << j)) == 0) { m_img->setPixel(m_pixel_x, m_pixel_y, qRgb(255, 255, 255)); } else { m_img->setPixel(m_pixel_x, m_pixel_y, qRgb(0, 0, 0)); } m_pixel_x++; if (m_pixel_x >= m_params.pixels_per_line) { m_pixel_x = 0; m_pixel_y++; break; } if (m_pixel_y >= m_params.lines) { break; } } m_frameRead++; } return true; } else if (m_params.depth == 8) { for (int i = 0; i < read_bytes; i++) { index = m_frameRead * 4; if ((index + 2) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index ] = readData[i]; imgBits[index + 1] = readData[i]; imgBits[index + 2] = readData[i]; m_frameRead++; } return true; } else if (m_params.depth == 16) { for (int i = 0; i < read_bytes; i++) { if (m_frameRead % 2 == 0) { index = m_frameRead * 2; if ((index + 2) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index ] = readData[i + 1]; imgBits[index + 1] = readData[i + 1]; imgBits[index + 2] = readData[i + 1]; } m_frameRead++; } return true; } break; case SANE_FRAME_RGB: if (m_params.depth == 8) { for (int i = 0; i < read_bytes; i++) { m_px_colors[m_px_c_index] = readData[i]; inc_color_index(m_px_c_index); m_frameRead++; if (m_px_c_index == 0) { if (m_pixel_y >= m_img->height()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); - m_imageResized = true; + renewImage(); } m_img->setPixel(m_pixel_x, m_pixel_y, qRgb(m_px_colors[0], m_px_colors[1], m_px_colors[2])); inc_pixel(m_pixel_x, m_pixel_y, m_params.pixels_per_line); } } return true; } else if (m_params.depth == 16) { for (int i = 0; i < read_bytes; i++) { m_frameRead++; if (m_frameRead % 2 == 0) { m_px_colors[m_px_c_index] = readData[i]; inc_color_index(m_px_c_index); if (m_px_c_index == 0) { if (m_pixel_y >= m_img->height()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); - m_imageResized = true; + renewImage(); } m_img->setPixel(m_pixel_x, m_pixel_y, qRgb(m_px_colors[0], m_px_colors[1], m_px_colors[2])); inc_pixel(m_pixel_x, m_pixel_y, m_params.pixels_per_line); } } } return true; } break; case SANE_FRAME_RED: if (m_params.depth == 8) { for (int i = 0; i < read_bytes; i++) { if (index_red8_to_argb8(m_frameRead) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index_red8_to_argb8(m_frameRead)] = readData[i]; m_frameRead++; } return true; } else if (m_params.depth == 16) { for (int i = 0; i < read_bytes; i++) { if (m_frameRead % 2 == 0) { if (index_red16_to_argb8(m_frameRead) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index_red16_to_argb8(m_frameRead)] = readData[i + 1]; } m_frameRead++; } return true; } break; case SANE_FRAME_GREEN: if (m_params.depth == 8) { for (int i = 0; i < read_bytes; i++) { if (index_green8_to_argb8(m_frameRead) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index_green8_to_argb8(m_frameRead)] = readData[i]; m_frameRead++; } return true; } else if (m_params.depth == 16) { for (int i = 0; i < read_bytes; i++) { if (m_frameRead % 2 == 0) { if (index_green16_to_argb8(m_frameRead) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index_green16_to_argb8(m_frameRead)] = readData[i + 1]; } m_frameRead++; } return true; } break; case SANE_FRAME_BLUE: if (m_params.depth == 8) { for (int i = 0; i < read_bytes; i++) { if (index_blue8_to_argb8(m_frameRead) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index_blue8_to_argb8(m_frameRead)] = readData[i]; m_frameRead++; } return true; } else if (m_params.depth == 16) { for (int i = 0; i < read_bytes; i++) { if (m_frameRead % 2 == 0) { if (index_blue16_to_argb8(m_frameRead) > m_img->byteCount()) { - // resize the image - *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + renewImage(); imgBits = m_img->bits(); - m_imageResized = true; } imgBits[index_blue16_to_argb8(m_frameRead)] = readData[i + 1]; } m_frameRead++; } return true; } break; } qWarning() << "Format" << m_params.format << "and depth" << m_params.depth << "is not yet supported by libksane!"; return false; } bool KSanePreviewImageBuilder::imageResized() { if (m_imageResized) { m_imageResized = false; return true; } return false; } + +void KSanePreviewImageBuilder::renewImage() +{ + // resize the image + *m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width()); + m_imageResized = true; +} } // NameSpace KSaneIface diff --git a/src/ksanepreviewimagebuilder.h b/src/ksanepreviewimagebuilder.h index 38a72c9..d844422 100644 --- a/src/ksanepreviewimagebuilder.h +++ b/src/ksanepreviewimagebuilder.h @@ -1,64 +1,66 @@ /* ============================================================ * * This file is part of the KDE project * * Description : Sane interface for KDE * * Copyright (C) 2009 by Kare Sars * Copyright (C) 2018 by Alexander Volkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see . * * ============================================================ */ #ifndef KSANE_PREVIEW_IMAGE_BUILDER_H #define KSANE_PREVIEW_IMAGE_BUILDER_H extern "C" { #include } class QImage; namespace KSaneIface { class KSanePreviewImageBuilder { public: KSanePreviewImageBuilder(QImage *img); void start(const SANE_Parameters ¶ms); void beginFrame(const SANE_Parameters ¶ms); bool copyToImage(const SANE_Byte readData[], int read_bytes); bool imageResized(); private: + void renewImage(); + SANE_Parameters m_params; int m_frameRead; int m_pixel_x; int m_pixel_y; int m_px_colors[3]; int m_px_c_index; QImage *m_img; bool m_imageResized; }; } #endif // KSANE_PREVIEW_IMAGE_BUILDER_H