⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qjpeghandler.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    for (uint j=0; j<cinfo.output_height; j++) {                        uchar *in = image.scanLine(j) + cinfo.output_width * 3;                        QRgb *out = (QRgb*)image.scanLine(j);                        for (uint i=cinfo.output_width; i--;) {                            in-=3;                            out[i] = qRgb(in[0], in[1], in[2]);                        }                    }                } else if (cinfo.out_color_space == JCS_CMYK) {                    for (uint j = 0; j < cinfo.output_height; ++j) {                        uchar *in = image.scanLine(j) + cinfo.output_width * 4;                        QRgb *out = (QRgb*)image.scanLine(j);                        for (uint i = cinfo.output_width; i--; ) {                            in-=4;                            int k = in[3];                            out[i] = qRgb(k * in[0] / 255, k * in[1] / 255, k * in[2] / 255);                        }                    }                }                if (cinfo.density_unit == 1) {                    image.setDotsPerMeterX(int(100. * cinfo.X_density / 2.54));                    image.setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54));                } else if (cinfo.density_unit == 2) {                    image.setDotsPerMeterX(int(100. * cinfo.X_density));                    image.setDotsPerMeterY(int(100. * cinfo.Y_density));                }            }        }        *outImage = image;    }    jpeg_destroy_decompress(&cinfo);    delete iod_src;    return !image.isNull();}struct my_jpeg_destination_mgr : public jpeg_destination_mgr {    // Nothing dynamic - cannot rely on destruction over longjump    QIODevice *device;    JOCTET buffer[max_buf];public:    my_jpeg_destination_mgr(QIODevice *);};#if defined(Q_C_CALLBACKS)extern "C" {#endifstaticvoid qt_init_destination(j_compress_ptr){}staticboolean qt_empty_output_buffer(j_compress_ptr cinfo){    my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;    int written = dest->device->write((char*)dest->buffer, max_buf);    if (written == -1)        (*cinfo->err->error_exit)((j_common_ptr)cinfo);    dest->next_output_byte = dest->buffer;    dest->free_in_buffer = max_buf;#if defined(Q_OS_UNIXWARE)    return B_TRUE;#else    return true;#endif}staticvoid qt_term_destination(j_compress_ptr cinfo){    my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;    qint64 n = max_buf - dest->free_in_buffer;    qint64 written = dest->device->write((char*)dest->buffer, n);    if (written == -1)        (*cinfo->err->error_exit)((j_common_ptr)cinfo);}#if defined(Q_C_CALLBACKS)}#endifinline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device){    jpeg_destination_mgr::init_destination = qt_init_destination;    jpeg_destination_mgr::empty_output_buffer = qt_empty_output_buffer;    jpeg_destination_mgr::term_destination = qt_term_destination;    this->device = device;    next_output_byte = buffer;    free_in_buffer = max_buf;}static bool write_jpeg_image(const QImage &sourceImage, QIODevice *device, int sourceQuality){    bool success = false;    QImage image = sourceImage;    struct jpeg_compress_struct cinfo;    JSAMPROW row_pointer[1];    row_pointer[0] = 0;    struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);    struct my_error_mgr jerr;    cinfo.err = jpeg_std_error(&jerr);    jerr.error_exit = my_error_exit;    if (!setjmp(jerr.setjmp_buffer)) {        jpeg_create_compress(&cinfo);        cinfo.dest = iod_dest;        cinfo.image_width = image.width();        cinfo.image_height = image.height();        QVector<QRgb> cmap = image.colorTable();        bool gray=false;        switch (image.depth()) {        case 1:        case 8:            gray = true;            for (int i = image.numColors(); gray && i--;) {                gray = gray & (qRed(cmap[i]) == qGreen(cmap[i]) &&                               qRed(cmap[i]) == qBlue(cmap[i]));            }            cinfo.input_components = gray ? 1 : 3;            cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;            break;        case 32:            cinfo.input_components = 3;            cinfo.in_color_space = JCS_RGB;        }        jpeg_set_defaults(&cinfo);        qreal diffInch = qAbs(image.dotsPerMeterX()*2.54/100. - qRound(image.dotsPerMeterX()*2.54/100.))                         + qAbs(image.dotsPerMeterY()*2.54/100. - qRound(image.dotsPerMeterY()*2.54/100.));        qreal diffCm = (qAbs(image.dotsPerMeterX()/100. - qRound(image.dotsPerMeterX()/100.))                        + qAbs(image.dotsPerMeterY()/100. - qRound(image.dotsPerMeterY()/100.)))*2.54;        if (diffInch < diffCm) {            cinfo.density_unit = 1; // dots/inch            cinfo.X_density = qRound(image.dotsPerMeterX()*2.54/100.);            cinfo.Y_density = qRound(image.dotsPerMeterY()*2.54/100.);        } else {            cinfo.density_unit = 2; // dots/cm            cinfo.X_density = (image.dotsPerMeterX()+50) / 100;            cinfo.Y_density = (image.dotsPerMeterY()+50) / 100;        }        int quality = sourceQuality >= 0 ? qMin(sourceQuality,100) : 75;#if defined(Q_OS_UNIXWARE)        jpeg_set_quality(&cinfo, quality, B_TRUE /* limit to baseline-JPEG values */);        jpeg_start_compress(&cinfo, B_TRUE);#else        jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */);        jpeg_start_compress(&cinfo, true);#endif        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];        int w = cinfo.image_width;        while (cinfo.next_scanline < cinfo.image_height) {            uchar *row = row_pointer[0];            switch (image.depth()) {            case 1:                if (gray) {                    uchar* data = image.scanLine(cinfo.next_scanline);                    if (image.format() == QImage::Format_MonoLSB) {                        for (int i=0; i<w; i++) {                            bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));                            row[i] = qRed(cmap[bit]);                        }                    } else {                        for (int i=0; i<w; i++) {                            bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));                            row[i] = qRed(cmap[bit]);                        }                    }                } else {                    uchar* data = image.scanLine(cinfo.next_scanline);                    if (image.format() == QImage::Format_MonoLSB) {                        for (int i=0; i<w; i++) {                            bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));                            *row++ = qRed(cmap[bit]);                            *row++ = qGreen(cmap[bit]);                            *row++ = qBlue(cmap[bit]);                        }                    } else {                        for (int i=0; i<w; i++) {                            bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));                            *row++ = qRed(cmap[bit]);                            *row++ = qGreen(cmap[bit]);                            *row++ = qBlue(cmap[bit]);                        }                    }                }                break;            case 8:                if (gray) {                    uchar* pix = image.scanLine(cinfo.next_scanline);                    for (int i=0; i<w; i++) {                        *row = qRed(cmap[*pix]);                        ++row; ++pix;                    }                } else {                    uchar* pix = image.scanLine(cinfo.next_scanline);                    for (int i=0; i<w; i++) {                        *row++ = qRed(cmap[*pix]);                        *row++ = qGreen(cmap[*pix]);                        *row++ = qBlue(cmap[*pix]);                        ++pix;                    }                }                break;            case 32: {                QRgb* rgb = (QRgb*)image.scanLine(cinfo.next_scanline);                for (int i=0; i<w; i++) {                    *row++ = qRed(*rgb);                    *row++ = qGreen(*rgb);                    *row++ = qBlue(*rgb);                    ++rgb;                }            }            }            jpeg_write_scanlines(&cinfo, row_pointer, 1);        }        jpeg_finish_compress(&cinfo);        jpeg_destroy_compress(&cinfo);        success = true;    } else {        jpeg_destroy_compress(&cinfo);        success = false;    }    delete iod_dest;    delete [] row_pointer[0];    return success;}QJpegHandler::QJpegHandler(){    quality = 75;}bool QJpegHandler::canRead() const{    if (canRead(device())) {        setFormat("jpeg");        return true;    }    return false;}bool QJpegHandler::canRead(QIODevice *device){    if (!device) {        qWarning("QJpegHandler::canRead() called with no device");        return false;    }    return device->peek(2) == "\xFF\xD8";}bool QJpegHandler::read(QImage *image){    if (!canRead())        return false;    return read_jpeg_image(device(), image, parameters);}bool QJpegHandler::write(const QImage &image){    return write_jpeg_image(image, device(), quality);}bool QJpegHandler::supportsOption(ImageOption option) const{    return option == Quality        || option == Size;// || option == Parameters;}QVariant QJpegHandler::option(ImageOption option) const{    if (option == Quality) {        return quality;    } else if (option == Size) {        if (canRead() && !device()->isSequential()) {            qint64 pos = device()->pos();            QImage image;            read_jpeg_image(device(), &image, "GetHeaderInformation");            device()->seek(pos);            return image.size();        }    }//    else if (option == Parameters)//        return parameters;    return QVariant();}void QJpegHandler::setOption(ImageOption option, const QVariant &value){    if (option == Quality)        quality = value.toInt();//    else if (option == Parameters)//        parameters = value.toByteArray();}QByteArray QJpegHandler::name() const{    return "jpeg";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -