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

📄 qjpeghandler.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    cinfo.scale_denom = 1;                } else if (cinfo.scale_denom < 4) {                    cinfo.scale_denom = 2;                } else if (cinfo.scale_denom < 8) {                    cinfo.scale_denom = 4;                } else {                    cinfo.scale_denom = 8;                }            }                        jpegSmoothScaler scaler(&cinfo, QString().sprintf("Scale( %d, %d, ScaleFree )",                                                              scaledSize.width(),                                                              scaledSize.height()).toLatin1().data());            *outImage = scaler.scale();#endif        } else {            if (cinfo.output_components == 3 || cinfo.output_components == 4) {                if (outImage->size() != QSize(cinfo.output_width, cinfo.output_height)                    || outImage->format() != QImage::Format_RGB32) {                    *outImage = QImage(cinfo.output_width, cinfo.output_height, QImage::Format_RGB32);                }            } else if (cinfo.output_components == 1) {                if (outImage->size() != QSize(cinfo.output_width, cinfo.output_height)                    || outImage->format() != QImage::Format_Indexed8) {                    *outImage = QImage(cinfo.output_width, cinfo.output_height, QImage::Format_Indexed8);                }                outImage->setNumColors(256);                for (int i=0; i<256; i++)                    outImage->setColor(i, qRgb(i,i,i));            } else {                // Unsupported format            }            if (outImage->isNull())                return false;            if (!outImage->isNull()) {                uchar* data = outImage->bits();                int bpl = outImage->bytesPerLine();                while (cinfo.output_scanline < cinfo.output_height) {                    uchar *d = data + cinfo.output_scanline * bpl;                    (void) jpeg_read_scanlines(&cinfo,                                               &d,                                               1);                }                (void) jpeg_finish_decompress(&cinfo);                if (cinfo.output_components == 3) {                    // Expand 24->32 bpp.                    for (uint j=0; j<cinfo.output_height; j++) {                        uchar *in = outImage->scanLine(j) + cinfo.output_width * 3;                        QRgb *out = (QRgb*)outImage->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 = outImage->scanLine(j) + cinfo.output_width * 4;                        QRgb *out = (QRgb*)outImage->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) {                    outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54));                    outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54));                } else if (cinfo.density_unit == 2) {                    outImage->setDotsPerMeterX(int(100. * cinfo.X_density));                    outImage->setDotsPerMeterY(int(100. * cinfo.Y_density));                }            }        }    }    jpeg_destroy_decompress(&cinfo);    delete iod_src;    return !outImage->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" {#endifstatic void qt_init_destination(j_compress_ptr){}static boolean 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}static void 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;    const QImage image = sourceImage;    const QVector<QRgb> cmap = image.colorTable();    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)) {        // WARNING:        // this if loop is inside a setjmp/longjmp branch        // do not create C++ temporaries here because the destructor may never be called        // if you allocate memory, make sure that you can free it (row_pointer[0])        jpeg_create_compress(&cinfo);        cinfo.dest = iod_dest;        cinfo.image_width = image.width();        cinfo.image_height = image.height();        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) {                    const 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 {                    const 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) {                    const uchar* pix = image.scanLine(cinfo.next_scanline);                    for (int i=0; i<w; i++) {                        *row = qRed(cmap[*pix]);                        ++row; ++pix;                    }                } else {                    const 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, scaledSize, quality);}bool QJpegHandler::write(const QImage &image){    return write_jpeg_image(image, device(), quality);}bool QJpegHandler::supportsOption(ImageOption option) const{    return option == Quality#ifndef QT_NO_IMAGE_SMOOTHSCALE        || option == ScaledSize#endif        || option == Size;}QVariant QJpegHandler::option(ImageOption option) const{    if (option == Quality) {        return quality;#ifndef QT_NO_IMAGE_SMOOTHSCALE    } else if  (option == ScaledSize) {        return scaledSize;#endif    } else if (option == Size) {        if (canRead() && !device()->isSequential()) {            qint64 pos = device()->pos();            QImage image;            read_jpeg_image(device(), &image, "GetHeaderInformation", scaledSize, quality);            device()->seek(pos);            return image.size();        }    }    return QVariant();}void QJpegHandler::setOption(ImageOption option, const QVariant &value){    if (option == Quality)        quality = value.toInt();#ifndef QT_NO_IMAGE_SMOOTHSCALE    else if ( option == ScaledSize )        scaledSize = value.toSize();#endif}QByteArray QJpegHandler::name() const{    return "jpeg";}

⌨️ 快捷键说明

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