Ejemplo n.º 1
0
void DkThumbNail::removeBlackBorder(QImage& img) {

	int rIdx = 0;
	bool nonblack = false;
	
	for ( ; rIdx < qRound(img.height()*0.1); rIdx++) {

		const QRgb* pixel = (QRgb*)(img.constScanLine(rIdx));

		for (int cIdx = 0; cIdx < img.width(); cIdx++, pixel++) {

			// > 50 due to jpeg (normally we would want it to be != 0)
			if (qRed(*pixel) > 50 || qBlue(*pixel) > 50 || qGreen(*pixel) > 50) {
				nonblack = true;
				break;
			}
		}

		if (nonblack)
			break;
	}

	// non black border?
	if (rIdx == -1 || rIdx > 15)
		return;

	int rIdxB = img.height()-1;
	nonblack = false;

	for ( ; rIdxB >= qRound(img.height()*0.9f); rIdxB--) {

		const QRgb* pixel = (QRgb*)(img.constScanLine(rIdxB));

		for (int cIdx = 0; cIdx < img.width(); cIdx++, pixel++) {

			if (qRed(*pixel) > 50 || qBlue(*pixel) > 50 || qGreen(*pixel) > 50) {
				nonblack = true;
				break;
			}
		}

		if (nonblack) {
			rIdxB--;
			break;
		}
	}

	// remove black borders
	if (rIdx < rIdxB)
		img = img.copy(0, rIdx, img.width(), rIdxB-rIdx);

}
Ejemplo n.º 2
0
void BlurElementPrivate::integralImage(const QImage &image,
                                       int oWidth, int oHeight,
                                       PixelU32 *integral)
{
    for (int y = 1; y < oHeight; y++) {
        auto line = reinterpret_cast<const QRgb *>(image.constScanLine(y - 1));

        // Reset current line summation.
        PixelU32 sum;

        for (int x = 1; x < oWidth; x++) {
            QRgb pixel = line[x - 1];

            // Accumulate pixels in current line.
            sum += pixel;

            // Offset to the current line.
            int offset = x + y * oWidth;

            // Offset to the previous line.
            // equivalent to x + (y - 1) * oWidth;
            int offsetPrevious = offset - oWidth;

            // Accumulate current line and previous line.
            integral[offset] = sum + integral[offsetPrevious];
        }
    }
}
Ejemplo n.º 3
0
inline QImage threshold(const QImage &src,
                        const QVector<int> &thresholds,
                        const QVector<int> &colors)
{
    QImage dst(src.size(), src.format());
    QVector<quint8> colorTable(256);
    int j = 0;

    for (int i = 0; i < colorTable.size(); i++) {
        if (j < thresholds.size() && i >= thresholds[j])
            j++;

        colorTable[i] = quint8(colors[j]);
    }

    for (int y = 0; y < src.height(); y++) {
        const quint8 *srcLine = src.constScanLine(y);
        quint8 *dstLine = dst.scanLine(y);

        for (int x = 0; x < src.width(); x++)
            dstLine[x] = colorTable[srcLine[x]];
    }

    return dst;
}
Ejemplo n.º 4
0
QColor QgsCompoundColorWidget::averageColor( const QImage &image ) const
{
  QRgb tmpRgb;
  int colorCount = 0;
  int sumRed = 0;
  int sumBlue = 0;
  int sumGreen = 0;
  //scan through image and sum rgb components
  for ( int heightIndex = 0; heightIndex < image.height(); ++heightIndex )
  {
    QRgb *scanLine = ( QRgb * )image.constScanLine( heightIndex );
    for ( int widthIndex = 0; widthIndex < image.width(); ++widthIndex )
    {
      tmpRgb = scanLine[widthIndex];
      sumRed += qRed( tmpRgb );
      sumBlue += qBlue( tmpRgb );
      sumGreen += qGreen( tmpRgb );
      colorCount++;
    }
  }
  //calculate average components as floats
  double avgRed = ( double )sumRed / ( 255.0 * colorCount );
  double avgGreen = ( double )sumGreen / ( 255.0 * colorCount );
  double avgBlue = ( double )sumBlue / ( 255.0 * colorCount );

  //create a new color representing the average
  return QColor::fromRgbF( avgRed, avgGreen, avgBlue );
}
Ejemplo n.º 5
0
  QList<QImage> split(const QImage& img)
  {
    QVector<bool> emptyLines(img.height(), true);
    for (int y = 0; y < img.height(); ++y) {
      const uchar* it = img.constScanLine(y);
      const uchar* end = it + img.width();
      while (it < end) {
        if (*it++ > 10) {
          emptyLines[y] = false;
          break;
        }
      }
    }

    QList<QImage> lines;
    for (int y = 0; y < img.height();) {
      if (emptyLines[y]) {
        ++y;
        continue;
      }

      QRect r(0, y, img.width(), 1);
      int height = 0;
      for (; y < img.height() && !emptyLines[y]; ++y)
        ++height;
      r.setHeight(height);

      if (height > 60 && height < 80) {
        lines += splitPath(img.copy(r));
      } else {
        lines << img.copy(r);
      }
    }
    return lines;
  }
static void placeImage(QImage& dst,int x,int y,const QImage& src) {
    int size = src.width()*4;
    for (int yy=0;yy<src.height();yy++) {
        const uchar* src_d = src.constScanLine(yy);
        uchar* dst_d = dst.scanLine(y+yy);
        dst_d += x*4;
        ::memcpy(dst_d,src_d,size);
    }
}
Ejemplo n.º 7
0
static bool writeWBMPData(QIODevice *iodev, const QImage &image)
{
    if (iodev) {
        int h = image.height();
        int bpl = (image.width() + 7) / 8;

        for (int l=0; l<h; l++) {
            if (iodev->write(reinterpret_cast<const char *>(image.constScanLine(l)), bpl) != bpl)
                return false;
        }
        return true;
    }
    return false;
}
Ejemplo n.º 8
0
QImage qmainstackwidget::toGray(QImage image)
{
	int height = image.height();
	int width = image.width();
	QImage ret(width, height, QImage::Format_Indexed8);
	ret.setColorCount(256);
	for (int i = 0; i < 256; i++)
	{
		ret.setColor(i, qRgb(i, i, i));
	}
	switch (image.format())
	{
	case QImage::Format_Indexed8:
		for (int i = 0; i < height; i++)
		{
			const uchar *pSrc = (uchar *)image.constScanLine(i);
			uchar *pDest = (uchar *)ret.scanLine(i);
			memcpy(pDest, pSrc, width);
		}
		break;
	case QImage::Format_RGB32:
	case QImage::Format_ARGB32:
	case QImage::Format_ARGB32_Premultiplied:
		for (int i = 0; i < height; i++)
		{
			const QRgb *pSrc = (QRgb *)image.constScanLine(i);
			uchar *pDest = (uchar *)ret.scanLine(i);

			for (int j = 0; j < width; j++)
			{
				pDest[j] = qGray(pSrc[j]);
			}
		}
		break;
	}
	return ret;
}
void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef imageRef, WKArrayRef repaintRects)
{
    QImage image;
    if (PlatformWebView::windowShapshotEnabled()) {
        WKPageRef page = TestController::shared().mainWebView()->page();
        WKPageForceRepaint(page, this, &forceRepaintDoneCallback);

        TestController::shared().runUntil(m_gotRepaint, TestController::ShortTimeout);

        if (m_gotRepaint)
            image = WKImageCreateQImage(TestController::shared().mainWebView()->windowSnapshotImage().get());
        else {
            m_error = true;
            m_errorMessage = "Timed out waiting for repaint\n";
            m_webProcessIsUnresponsive = true;
            return;
        }
    } else
        image = WKImageCreateQImage(imageRef);

    if (repaintRects) {
        QImage mask(image.size(), image.format());
        mask.fill(QColor(0, 0, 0, 0.66 * 255));

        QPainter maskPainter(&mask);
        maskPainter.setCompositionMode(QPainter::CompositionMode_Source);
        size_t count = WKArrayGetSize(repaintRects);
        for (size_t i = 0; i < count; ++i) {
            WKRect wkRect = WKRectGetValue(static_cast<WKRectRef>(WKArrayGetItemAtIndex(repaintRects, i)));
            QRectF rect(wkRect.origin.x, wkRect.origin.y, wkRect.size.width, wkRect.size.height);
            maskPainter.fillRect(rect, Qt::transparent);
        }

        QPainter painter(&image);
        painter.drawImage(image.rect(), mask);
    }

    QCryptographicHash hash(QCryptographicHash::Md5);
    for (unsigned row = 0; row < image.height(); ++row)
        hash.addData(reinterpret_cast<const char*>(image.constScanLine(row)), image.bytesPerLine());

    QByteArray actualHash = hash.result().toHex();
    ASSERT(actualHash.size() == 32);
    if (!compareActualHashToExpectedAndDumpResults(actualHash)) {
        image.setText("checksum", actualHash);
        dumpImage(image);
    }
}
Ejemplo n.º 10
0
void FilterOp::filterHorizontally(QImage &src, QRgb *trg, const QRgb *rgba)
{
    const uchar* pixels = src.constScanLine(0);
    int sourcePitch = src.bytesPerLine();

    for (int k = 0; k < srcHeight; ++k)
    {
        int destOfsY = dstWidth * k;
        for (int i = dstWidth - 1; i >= 0 ; --i)
        {
            float red = 0;
            float green = 0;
            float blue = 0;
            float alpha = 0;

            int max = horizontalSubsamplingData.numberOfSamples[i];
            int index = i * horizontalSubsamplingData.matrixWidth;

            for (int j = max - 1; j >= 0; --j)
            {
                int ofsX = horizontalSubsamplingData.pixelPositions[index];
                int palIdx = pixels[ofsX] & 0xff;
                float w = horizontalSubsamplingData.weights[index];
                red += qRed(rgba[palIdx]) * w;
                green += qGreen(rgba[palIdx]) * w;
                blue+= qBlue(rgba[palIdx]) * w;
                alpha += qAlpha(rgba[palIdx]) * w;
                index++;
            }

            int ri = std::max((int)red, 0);
            ri = std::min(ri, 255);

            int gi = std::max((int)green, 0);
            gi = std::min(gi, 255);

            int bi = std::max((int)blue, 0);
            bi = std::min(bi, 255);

            int ai = std::max((int)alpha, 0);
            ai = std::min(ai, 255);

            trg[i + destOfsY] = qRgba(ri, gi, bi, ai);
        }
        pixels += sourcePitch;
    }
}
Ejemplo n.º 11
0
inline QVector<int> histogram(const QImage &image)
{
    QVector<int> histogram(256, 0);

    for (int y = 0; y < image.height(); y++) {
        const quint8 *line = reinterpret_cast<const quint8 *>(image.constScanLine(y));

        for (int x = 0; x < image.width(); x++)
            histogram[line[x]]++;
    }

    // Since we use sum tables add one more to avoid unexistent colors.
    for (int i = 0; i < histogram.size(); i++)
        histogram[i]++;

    return histogram;
}
Ejemplo n.º 12
0
void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef imageRef, WKArrayRef repaintRects)
{
    //FIXME: https://bugs.webkit.org/show_bug.cgi?id=68870
    UNUSED_PARAM(repaintRects);

    QImage image = WKImageCreateQImage(imageRef);
    QCryptographicHash hash(QCryptographicHash::Md5);
    for (unsigned row = 0; row < image.height(); ++row)
        hash.addData(reinterpret_cast<const char*>(image.constScanLine(row)), image.bytesPerLine());

    QByteArray actualHash = hash.result().toHex();
    ASSERT(actualHash.size() == 32);
    if (!compareActualHashToExpectedAndDumpResults(actualHash)) {
        image.setText("checksum", actualHash);
        dumpImage(image);
    }
}
Ejemplo n.º 13
0
static void addImage( FlifEncoder& encoder, const QImage& in ) {
    FlifImage img( in.width(), in.height() );

    auto buffer = std::make_unique<uint8_t[]>( in.width() * 4 );
    for( int iy=0; iy<in.height(); iy++ ) {
        auto line = (const QRgb*)in.constScanLine( iy );

        for( int ix=0; ix<in.width(); ix++ ) {
            buffer[ix*4+0] = qRed( line[ix] );
            buffer[ix*4+1] = qGreen( line[ix] );
            buffer[ix*4+2] = qBlue( line[ix] );
            buffer[ix*4+3] = qAlpha( line[ix] );
        }

        img.writeRowRgba8( iy, buffer.get(), in.width() * 4 );
    }

    encoder.addImage( img ); //TODO: investigate memory model
}
Ejemplo n.º 14
0
QColor get_average_color(QImage src){
	if (src.depth() < 32)
		src = src.convertToFormat(QImage::Format_ARGB32);
	quint64 avg[3] = {0};
	unsigned pixel_count=0;
	for (auto y = src.height() * 0; y < src.height(); y++){
		const uchar *p = src.constScanLine(y);
		for (auto x = src.width() * 0; x < src.width(); x++){
			avg[0] += quint64(p[2]) * quint64(p[3]) / 255;
			avg[1] += quint64(p[1]) * quint64(p[3]) / 255;
			avg[2] += quint64(p[0]) * quint64(p[3]) / 255;
			p += 4;
			pixel_count++;
		}
	}
	for (int a = 0; a < 3; a++)
		avg[a] /= pixel_count;
	return QColor(avg[0], avg[1], avg[2]);
}
Ejemplo n.º 15
0
QImage imageForPixbuf(const GdkPixbuf* pixbuf, const QString &name)
{
    QImage result;
    if (gdk_pixbuf_get_n_channels(pixbuf) == 3 && gdk_pixbuf_get_bits_per_sample(pixbuf) == 8 && !gdk_pixbuf_get_has_alpha(pixbuf)) {
        const QImage image = QImage(gdk_pixbuf_get_pixels(pixbuf),
                             gdk_pixbuf_get_width(pixbuf),
                             gdk_pixbuf_get_height(pixbuf),
                             gdk_pixbuf_get_rowstride(pixbuf),
                             QImage::QImage::Format_RGB888);
        result = image.convertToFormat(QImage::Format_ARGB32);
    } else {
        if (gdk_pixbuf_get_n_channels(pixbuf) != 4 || gdk_pixbuf_get_bits_per_sample(pixbuf) != 8 || !gdk_pixbuf_get_has_alpha(pixbuf)) {
            UQ_WARNING << "Pixbuf is not in the expected format. Trying to load it anyway, will most likely fail" << name;
        }
        const QImage image = QImage(gdk_pixbuf_get_pixels(pixbuf),
                             gdk_pixbuf_get_width(pixbuf),
                             gdk_pixbuf_get_height(pixbuf),
                             gdk_pixbuf_get_rowstride(pixbuf),
                             QImage::Format_ARGB32);

#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
        /* ABGR → ARGB */
        result = image.rgbSwapped();
#else
        /* ABGR → BGRA */
        /* Reference: https://bugs.launchpad.net/unity-2d/+bug/758782 */
        result = QImage(image.size(), image.format());
        for (int i = 0; i < swappedImage.height(); ++i) {
            QRgb* p = (QRgb*) image.constScanLine(i);
            QRgb* q = (QRgb*) swappedImage.scanLine(i);
            QRgb* end = p + image.width();
            while (p < end) {
                *q = qRgba(qAlpha(*p), qRed(*p), qGreen(*p), qBlue(*p));
                p++;
                q++;
            }
        }
#endif
    }

    return result;
}
Ejemplo n.º 16
0
QImage GaussianFilter::gaussianBlur(const QImage &img) const
{
	QImage result(img.size(), QImage::Format_Indexed8);
	{
		QVector<QRgb> colorTable;
		colorTable.reserve(256);
		for (int i = 0; i < 256; i++) {
			colorTable << qRgb(i, i, i);
		}
		result.setColorTable(colorTable);
	}
	const int kernelSize = mHalfSize * 2 + 1;
	for (int y = 0; y < img.height(); y++) {
		for (int x = 0; x < img.width(); x++) {
			qreal sum = 0;
			for (int ky = -mHalfSize; ky <= mHalfSize; ky++) {
				const int yTemp = y + ky;
				int yIdx = yTemp;
				if (yTemp >= img.height()) {
					yIdx = img.height() - (yTemp - img.height()) - 1;
				} else if (yTemp < 0) {
					yIdx = -yTemp;
				}
				const uchar *dy = img.constScanLine(yIdx);
				for (int kx = -mHalfSize; kx <= mHalfSize; kx++) {
					const int xTemp = x + kx;
					int xIdx = xTemp;
					if (xTemp >= img.width()) {
						xIdx = img.width() - (xTemp - img.width()) - 1;
					} else if (xTemp < 0) {
						xIdx = -xTemp;
					}
					sum += dy[xIdx] * mKernel.at((ky + mHalfSize) * kernelSize + kx + mHalfSize);
				}
			}
			sum *= mScale;
			const int iSum = sum; //qBound(0, sum, 255)
			result.setPixel(x, y, iSum);
		}
	}
	return result;
}
Ejemplo n.º 17
0
    jobject createBitmap(QImage img, JNIEnv *env)
    {
        if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
            img = img.convertToFormat(QImage::Format_ARGB32);

        jobject bitmap = env->CallStaticObjectMethod(m_bitmapClass,
                                                     m_createBitmapMethodID,
                                                     img.width(),
                                                     img.height(),
                                                     img.format() == QImage::Format_ARGB32
                                                        ? m_ARGB_8888_BitmapConfigValue
                                                        : m_RGB_565_BitmapConfigValue);
        if (!bitmap)
            return 0;

        AndroidBitmapInfo info;
        if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {
            env->DeleteLocalRef(bitmap);
            return 0;
        }

        void *pixels;
        if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
            env->DeleteLocalRef(bitmap);
            return 0;
        }

        if (info.stride == uint(img.bytesPerLine())
                && info.width == uint(img.width())
                && info.height == uint(img.height())) {
            memcpy(pixels, img.constBits(), info.stride * info.height);
        } else {
            uchar *bmpPtr = static_cast<uchar *>(pixels);
            const unsigned width = qMin(info.width, (uint)img.width()); //should be the same
            const unsigned height = qMin(info.height, (uint)img.height()); //should be the same
            for (unsigned y = 0; y < height; y++, bmpPtr += info.stride)
                memcpy(bmpPtr, img.constScanLine(y), width);
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return bitmap;
    }
Ejemplo n.º 18
0
const QImage TextureUsage::process2DImageColor(const QImage& srcImage, bool& validAlpha, bool& alphaAsMask) {
    QImage image = srcImage;
    validAlpha = false;
    alphaAsMask = true;
    const uint8 OPAQUE_ALPHA = 255;
    const uint8 TRANSPARENT_ALPHA = 0;
    if (image.hasAlphaChannel()) {
        std::map<uint8, uint32> alphaHistogram;

        if (image.format() != QImage::Format_ARGB32) {
            image = image.convertToFormat(QImage::Format_ARGB32);
        }

        // Actual alpha channel? create the histogram
        for (int y = 0; y < image.height(); ++y) {
            const QRgb* data = reinterpret_cast<const QRgb*>(image.constScanLine(y));
            for (int x = 0; x < image.width(); ++x) {
                auto alpha = qAlpha(data[x]);
                alphaHistogram[alpha] ++;
                validAlpha = validAlpha || (alpha != OPAQUE_ALPHA);
            }
        }

        // If alpha was meaningfull refine
        if (validAlpha && (alphaHistogram.size() > 1)) {
            auto totalNumPixels = image.height() * image.width();
            auto numOpaques = alphaHistogram[OPAQUE_ALPHA];
            auto numTransparents = alphaHistogram[TRANSPARENT_ALPHA];
            auto numTranslucents = totalNumPixels - numOpaques - numTransparents;

            alphaAsMask = ((numTranslucents / (double)totalNumPixels) < 0.05);
        }
    }

    if (!validAlpha && image.format() != QImage::Format_RGB888) {
        image = image.convertToFormat(QImage::Format_RGB888);
    }

    return image;
}
Ejemplo n.º 19
0
void CaViewerCore::beginCalcIntensity(QList<QGraphicsPixmapItem*> lRoi)
{
//    static const QString sProgressFormat = QObject::tr("Calculating... %p%");
    m_lockImage->lockForRead();
    QList<QList<QImage> > maskByHeight;
    QList<QList<QGraphicsPixmapItem*> > lRef;
    QList<QList<QPoint> > lPos;
    QList<QList<EigenRealVector*> > lIntensityRef;
    QList<EigenRealVector*> lRetIntensity;
    for(int count = 0; count < m_lImage->size(); ++count)
    {
        maskByHeight << QList<QImage>();
        lRef << QList<QGraphicsPixmapItem*>();
        lPos << QList<QPoint>();
        lIntensityRef << QList<EigenRealVector*>();
    }

    //  Set group by height
    const int timeSize = m_lImage->first().size();
    for(int count = 0; count < lRoi.size(); ++count)
    {
        QGraphicsPixmapItem* const roi = lRoi.at(count);
        const int height = roi->zValue();
        maskByHeight[height] << roi->pixmap().toImage();
        lRef[height] << lRoi.at(count);
        lPos[height] << roi->pos().toPoint();
        EigenRealVector* vec = new EigenRealVector();
        *vec = EigenRealVector::Zero(timeSize);
        lRetIntensity << vec;
        lIntensityRef[height] << vec;
    }

    //  Sum
    for(int height = 0; height < maskByHeight.size(); ++height)
    {
//#pragma omp parallel for schedule(static)
        for(int time = 0; time < timeSize; ++time)
        {
            const cv::Mat_<quint16> image = m_lImage->at(height).at(time);
            for(int count = 0; count < maskByHeight[height].size(); ++count)
            {
                const QImage mask = maskByHeight.at(height).at(count);
                qreal* const buf = static_cast<qreal*>(lIntensityRef.at(height).at(count)->data());
                const QPoint offset = lPos.at(height).at(count);
                for(int row = 0; row < mask.height(); ++row)
                {
                    const QRgb* const maskVal = reinterpret_cast<const QRgb*>(mask.constScanLine(row));
                    const quint16* const imgVal = reinterpret_cast<const quint16*>(image.data + (row + offset.y()) * image.step);

                    for(int col = 0; col < mask.width(); ++col)
                         buf[time] += static_cast<qreal>(imgVal[col + offset.x()]) * qAlpha(maskVal[col]);
                }
            }
        }

//        emit changedProgressValue(100.0 * height / maskByHeight.size(), sProgressFormat);
    }
    m_lockImage->unlock();

    //  Normalize
    for(int count = 0; count < lRetIntensity.size(); ++count)
    {
        EigenRealVector* const intensity = lRetIntensity.at(count);
        intensity->array() -= intensity->minCoeff();
        *intensity /= intensity->maxCoeff();
//        std::stringstream stream;
//        stream << "Roi " << height << count << ":\n" << *intensity << "\n";
//        qDebug() << QString(stream.str().c_str());
    }

    emit finishedCalcIntensity(lRoi, lRetIntensity);
//    beginCalcFrenetFrame(lRetIntensity);
    beginCalcPCA(lRetIntensity);
}
Ejemplo n.º 20
0
static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQuality)
{
    bool success = false;
    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.format()) {
        case QImage::Format_Mono:
        case QImage::Format_MonoLSB:
        case QImage::Format_Indexed8:
            gray = true;
            for (int i = image.colorCount(); 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;
        default:
            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.format()) {
            case QImage::Format_Mono:
            case QImage::Format_MonoLSB:
                if (gray) {
                    const uchar* data = image.constScanLine(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.constScanLine(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]);
                        }
                    }
                }
Ejemplo n.º 21
0
void VideoThumbnailer::Private::slotProcessframe(QVideoFrame frm)
{
    if (player->mediaStatus() != QMediaPlayer::BufferedMedia ||
        player->position()    <= 0)
    {
        if (++errorCount > 1000)
        {
            qCDebug(DIGIKAM_GENERAL_LOG) << "Error: Video data are corrupted from " << fileName();
            isReady = true;
            player->setMedia(QMediaContent());
            dd->emit signalThumbnailFailed(filePath());
            return;
        }
        else
        {
            player->setPosition(++position);
            return;
        }
    }

    qCDebug(DIGIKAM_GENERAL_LOG) << "Video frame extraction from " << fileName()
                                 << " at position " << position;

    if (!frm.isValid())
    { 
        qCDebug(DIGIKAM_GENERAL_LOG) << "Error: Video frame is not valid.";
        isReady = true;
        player->setMedia(QMediaContent());
        dd->emit signalThumbnailFailed(filePath());
        return;
    }

    QImage img = imageFromVideoFrame(frm);

    if (!img.isNull())
    {
        img = img.scaled(thumbSize, thumbSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);

        if (createStrip && img.width() > strip.width() && img.height() > strip.height())
        {
            // Add a video strip on the left side of video thumb.

            for (int y = 0; y < img.height(); y += strip.height())
            {
                for (int ys = 0 ; ys < strip.height() ; ys++)
                {
                    int pos = y + ys;

                    if (pos < img.height())
                    {
                        memcpy((void*)img.constScanLine(pos), (void*)strip.constScanLine(ys), strip.bytesPerLine());
                    }
                }
            }
        }

        qCDebug(DIGIKAM_GENERAL_LOG) << "Video frame extracted with size " << img.size();

        isReady = true;
        player->setMedia(QMediaContent());
        dd->emit signalThumbnailDone(filePath(), img.copy());
    }
    else
    {
        qCDebug(DIGIKAM_GENERAL_LOG) << "Video frame format is not supported: " << frm;

        isReady = true;
        player->setMedia(QMediaContent());
        dd->emit signalThumbnailFailed(filePath());
    }
}
Ejemplo n.º 22
0
QVector<float> AutoCorrelation::extract(const QImage &data, const int &x, const int &y) const
{
    const int w = mSize.width();
    const int h = mSize.height();
    const int dw = data.width();
    const int dh = data.height();
    ComplexArray *ca = new ComplexArray(boost::extents[w][h]);

    for (int ay = 0; ay < h; ay++) {
        int py = (y - h / 2 + ay) + dh;
        while (py >= dh) {
            py -= dh;
        }
        #ifdef HAS_IMAGE_CONSTSCANLINE
            const uchar *d = data.constScanLine(py);
        #else
            const uchar *d = data.scanLine(py);
        #endif
        for (int ax = 0; ax < w; ax++) {
            int px = (x - w / 2 + ax) + dw;
            while (px >= dw) {
                px -= dw;
            }
            (*ca)[ay][ax] = Complex(d[px], 0);
        }
    }
    perform(ca);

    float minm = 0;
    float maxm = 0;
    for (int j = 0; j < w; j++) {
        for (int k = 0; k < h; k++) {
            float magnitude = (*ca)[j][k].abs();
            if (magnitude > maxm) {
                maxm = magnitude;
            } else if (magnitude < minm) {
                minm = magnitude;
            }
        }
    }

    float c = 255.0 / log(1.0 + abs(maxm - minm));

    TwoDArray *img = new TwoDArray(boost::extents[w][h]);
    TwoDArray *flip = new TwoDArray(boost::extents[w][h]);

    for (int ay = 0; ay < h; ay++) {
        int py = (y - h / 2 + ay) + dh;
        while (py >= dh) {
            py -= dh;
        }
        #ifdef HAS_IMAGE_CONSTSCANLINE
            const uchar *d = data.constScanLine(py);
        #else
            const uchar *d = data.scanLine(py);
        #endif
        for (int ax = 0; ax < w; ax++) {
            int px = (x - w / 2 + ax) + dw;
            while (px >= dw) {
                px -= dw;
            }
            const float f = c * log(1.0 + (*ca)[ay][ax].abs());
            //const float f = d[px];
            (*img)[ay][ax] = f;
            (*flip)[ay][w - ax - 1] = f;
        }
    }

    QVector<float> result(h);
    float *resultPtr = result.data();
    for (int i = 0; i < h; i++) {
        for (int ay = 0; ay < h; ay++) {
            for (int ax = 0; ax < w; ax++) {
                const float f = float((*img)[ay][ax] * (*flip)[ay][(ax + i + w - 1) % w]) / float(65535);
                resultPtr[i] += f;
            }
        }
    }

    delete ca;
    delete img;
    delete flip;

    return result;
}
Ejemplo n.º 23
0
DtwImagePrivate::DtwImagePrivate(DtwImage *q, QImage img)
    : q_ptr(q), size(img.size()), NM(size.height() * size.width()),
      colors(NM), cells(NM),
      startingCell(0)
{
    BENCHMARK_START();
    if (img.format() != q->DTW_FORMAT)
        img = img.convertToFormat(q->DTW_FORMAT, Qt::AutoColor);
    const int height = size.height();
    const int width  = size.width();
    if (height < 3 || width < 3)  throw std::invalid_argument("Incorrect image dimensions");
    //Fillin colors
    {
        int k = 0;
        for (int i = 0; i < height; i++) {
            const QRgb* rawLine = reinterpret_cast<const QRgb*>(img.constScanLine(i));
            for (int j = 0; j < width; j++)
            {
                colors[k++] = rawLine[j];
            }
        }
    }

    //Establish connections and calculate energy
    {
        const int down = width;
        const int right = 1;
        cells[0].neighbours[LEFT] = INVALID_INDEX;
        cells[0].neighbours[UP] = INVALID_INDEX;
        cells[0].neighbours[RIGHT] = right;
        cells[0].neighbours[DOWN] = down;
#ifdef DIAGONAL_NEIGHBOURS
        cells[0].neighbours[DOWN_LEFT] = INVALID_INDEX;
        cells[0].neighbours[UP_LEFT] = INVALID_INDEX;
        cells[0].neighbours[UP_RIGHT] = INVALID_INDEX;
        cells[0].neighbours[DOWN_RIGHT] = down + 1;
#endif
        cells[0].energy = dualGradientEnergy(0, right, 0, down);
    }
    for (int j = 1; j < width - 1; j++)
    {
        const int down = j + width;
        const int right = j + 1;
        const int left = j - 1;
        cells[j].neighbours[UP] = INVALID_INDEX;
        cells[j].neighbours[RIGHT] = right;
        cells[j].neighbours[DOWN] = down;
        cells[j].neighbours[LEFT] = left;
#ifdef DIAGONAL_NEIGHBOURS
        cells[j].neighbours[UP_LEFT] = INVALID_INDEX;
        cells[j].neighbours[UP_RIGHT] = INVALID_INDEX;
        cells[j].neighbours[DOWN_RIGHT] = down + 1;
        cells[j].neighbours[DOWN_LEFT] = down - 1;
#endif

        cells[j].energy = dualGradientEnergy(left, right, j, down);
    }
    {
        int k = width - 1;
        const int down = k + width;;
        const int left = k - 1;
        cells[k].neighbours[UP] = INVALID_INDEX;
        cells[k].neighbours[RIGHT] = INVALID_INDEX;
        cells[k].neighbours[DOWN] = down;
        cells[k].neighbours[LEFT] = left;
#ifdef DIAGONAL_NEIGHBOURS
        cells[k].neighbours[UP_LEFT] = INVALID_INDEX;
        cells[k].neighbours[UP_RIGHT] = INVALID_INDEX;
        cells[k].neighbours[DOWN_RIGHT] = INVALID_INDEX;
        cells[k].neighbours[DOWN_LEFT] = down - 1;
#endif
        cells[k].energy = dualGradientEnergy( left, k, k, down );
    }
    int k = width;
    for (int i = 1; i < height - 1; i++) {
        {
            const int up = k - width;
            const int down = k + width;
            const int right = k + 1;
            cells[k].neighbours[LEFT] = INVALID_INDEX;
            cells[k].neighbours[UP] = up;
            cells[k].neighbours[RIGHT] = right;
            cells[k].neighbours[DOWN] = down;
#ifdef DIAGONAL_NEIGHBOURS
            cells[k].neighbours[DOWN_LEFT] = INVALID_INDEX;
            cells[k].neighbours[UP_LEFT] = INVALID_INDEX;
            cells[k].neighbours[DOWN_RIGHT] = down + 1;
            cells[k].neighbours[UP_RIGHT] = up + 1;
#endif
            cells[k].energy = dualGradientEnergy( k, right, up, down );
            k++;
        }
        for (int j = 1; j < width - 1; j++)
        {
            const int up = k - width;
            const int down = k + width;
            const int left = k - 1;
            const int right = k + 1;
            cells[k].neighbours[UP] = up;
            cells[k].neighbours[RIGHT] = right;
            cells[k].neighbours[DOWN] = down;
            cells[k].neighbours[LEFT] = left;
#ifdef DIAGONAL_NEIGHBOURS
            cells[k].neighbours[UP_LEFT] = up - 1;
            cells[k].neighbours[UP_RIGHT] = up + 1;
            cells[k].neighbours[DOWN_RIGHT] = down + 1;
            cells[k].neighbours[DOWN_LEFT] = down - 1;
#endif
            cells[k].energy = dualGradientEnergy( left, right, up, down );
            k++;
        }
        {
            const int up = k - width;
            const int down = k + width;
            const int left = k - 1;
            cells[k].neighbours[UP] =  up;
            cells[k].neighbours[RIGHT] = INVALID_INDEX;
            cells[k].neighbours[DOWN] = down;
            cells[k].neighbours[LEFT] = left;
#ifdef DIAGONAL_NEIGHBOURS
            cells[k].neighbours[UP_LEFT] =  up - 1;
            cells[k].neighbours[UP_RIGHT] =  INVALID_INDEX;
            cells[k].neighbours[DOWN_RIGHT] = INVALID_INDEX;
            cells[k].neighbours[DOWN_LEFT] = down - 1;
#endif
            cells[k].energy = dualGradientEnergy( left, k, up, down );
            k++;
        }
    }
    {
        const int up = k - width;
        const int right = k + 1;
        cells[k].neighbours[LEFT] = INVALID_INDEX;
        cells[k].neighbours[UP] = up;
        cells[k].neighbours[RIGHT] = right;
        cells[k].neighbours[DOWN] = INVALID_INDEX;
#ifdef DIAGONAL_NEIGHBOURS
        cells[k].neighbours[DOWN_LEFT] = INVALID_INDEX;
        cells[k].neighbours[UP_LEFT] = INVALID_INDEX;
        cells[k].neighbours[UP_RIGHT] = up + 1;
        cells[k].neighbours[DOWN_RIGHT] = INVALID_INDEX;
#endif
        cells[k].energy = dualGradientEnergy( k, right, up, k );
        k++;
    }
    for (int j = 1; j < width - 1; j++)
    {
        const int up = k - width;
        const int left = k - 1;
        const int right = k + 1;
        cells[k].neighbours[UP] = up;
        cells[k].neighbours[RIGHT] = right;
        cells[k].neighbours[DOWN] = INVALID_INDEX;
        cells[k].neighbours[LEFT] = left;
#ifdef DIAGONAL_NEIGHBOURS
        cells[k].neighbours[UP_LEFT] = up - 1;
        cells[k].neighbours[UP_RIGHT] = up + 1;
        cells[k].neighbours[DOWN_RIGHT] = INVALID_INDEX;
        cells[k].neighbours[DOWN_LEFT] = INVALID_INDEX;
#endif
        cells[k].energy = dualGradientEnergy( left, right, up, k );
        k++;
    }
    {
        const int up = k - width;
        const int left = k - 1;
        cells[k].neighbours[UP] =  up;
        cells[k].neighbours[RIGHT] = INVALID_INDEX;
        cells[k].neighbours[DOWN] = INVALID_INDEX;
        cells[k].neighbours[LEFT] = left;
#ifdef DIAGONAL_NEIGHBOURS
        cells[k].neighbours[UP_LEFT] =  up - 1;
        cells[k].neighbours[UP_RIGHT] =  INVALID_INDEX;
        cells[k].neighbours[DOWN_RIGHT] = INVALID_INDEX;
        cells[k].neighbours[DOWN_LEFT] = INVALID_INDEX;
#endif
        cells[k].energy = dualGradientEnergy( left, k, up, k );
    }
    Q_ASSERT(++k == NM);
    BENCHMARK_STOP();
}
Ejemplo n.º 24
0
void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
{
  int nCols = srcImage.width();
  int nRows = srcImage.height();

  int pos = 0;
  QRgb px;
  int *redMatrix = new int[ nCols * nRows ];
  int *greenMatrix = new int[ nCols * nRows ];
  int *blueMatrix = new int[ nCols * nRows ];
  int *alphaMatrix = new int[ nCols * nRows ];

  for ( int heightIndex = 0; heightIndex < nRows; ++heightIndex )
  {
    QRgb* scanLine = ( QRgb* )srcImage.constScanLine( heightIndex );
    for ( int widthIndex = 0; widthIndex < nCols; ++widthIndex )
    {
      px = scanLine[widthIndex];
      int alpha = qAlpha( px );
      alphaMatrix[pos] = alpha;
      redMatrix[pos] = qRed( px );
      greenMatrix[pos] = qGreen( px );
      blueMatrix[pos] = qBlue( px );

      pos++;
    }
  }

  //derivative x
  double* xDerivativeMatrixRed = new double[ nCols * nRows ];
  xDerivativeMatrix( nCols, nRows, xDerivativeMatrixRed, redMatrix );
  double* xDerivativeMatrixGreen = new double[ nCols * nRows ];
  xDerivativeMatrix( nCols, nRows, xDerivativeMatrixGreen, greenMatrix );
  double* xDerivativeMatrixBlue = new double[ nCols * nRows ];
  xDerivativeMatrix( nCols, nRows, xDerivativeMatrixBlue, blueMatrix );
  double* xDerivativeMatrixAlpha = new double[ nCols * nRows ];
  xDerivativeMatrix( nCols, nRows, xDerivativeMatrixAlpha, alphaMatrix );

  //derivative y
  double* yDerivativeMatrixRed = new double[ nCols * nRows ];
  yDerivativeMatrix( nCols, nRows, yDerivativeMatrixRed, redMatrix );
  double* yDerivativeMatrixGreen = new double[ nCols * nRows ];
  yDerivativeMatrix( nCols, nRows, yDerivativeMatrixGreen, greenMatrix );
  double* yDerivativeMatrixBlue = new double[ nCols * nRows ];
  yDerivativeMatrix( nCols, nRows, yDerivativeMatrixBlue, blueMatrix );
  double* yDerivativeMatrixAlpha = new double[ nCols * nRows ];
  yDerivativeMatrix( nCols, nRows, yDerivativeMatrixAlpha, alphaMatrix );

  //compute output
  double nSrcPerDstX = ( double ) srcImage.width() / ( double ) dstImage.width();
  double nSrcPerDstY = ( double ) srcImage.height() / ( double ) dstImage.height();

  double currentSrcRow = nSrcPerDstY / 2.0 - 0.5;
  double currentSrcCol;
  int currentSrcColInt;
  int currentSrcRowInt;
  int lastSrcColInt = -100;
  int lastSrcRowInt = -100;

  //bernstein polynomials
  double bp0u, bp1u, bp2u, bp3u, bp0v, bp1v, bp2v, bp3v;
  double u, v;

  for ( int y = 0; y < dstImage.height(); ++y )
  {
    currentSrcRowInt = floor( currentSrcRow );
    v = currentSrcRow - currentSrcRowInt;

    currentSrcCol = nSrcPerDstX / 2.0 - 0.5;

    QRgb* scanLine = ( QRgb* )dstImage.scanLine( y );
    for ( int x = 0; x < dstImage.width(); ++x )
    {
      currentSrcColInt = floor( currentSrcCol );
      u = currentSrcCol - currentSrcColInt;

      //handle eight edge-cases
      if (( currentSrcRowInt < 0 || currentSrcRowInt >= ( srcImage.height() - 1 ) || currentSrcColInt < 0 || currentSrcColInt >= ( srcImage.width() - 1 ) ) )
      {
        QRgb px1, px2;
        //pixels at the border of the source image needs to be handled in a special way
        if ( currentSrcRowInt < 0 && currentSrcColInt < 0 )
        {
          scanLine[x] = srcImage.pixel( 0, 0 );
        }
        else if ( currentSrcRowInt < 0 && currentSrcColInt >= ( srcImage.width() - 1 ) )
        {
          scanLine[x] = srcImage.pixel( srcImage.width() - 1, 0 );
        }
        else if ( currentSrcRowInt >= ( srcImage.height() - 1 ) && currentSrcColInt >= ( srcImage.width() - 1 ) )
        {
          scanLine[x] = srcImage.pixel( srcImage.width() - 1, srcImage.height() - 1 );
        }
        else if ( currentSrcRowInt >= ( srcImage.height() - 1 ) && currentSrcColInt < 0 )
        {
          scanLine[x] = srcImage.pixel( 0, srcImage.height() - 1 );
        }
        else if ( currentSrcRowInt < 0 )
        {
          px1 = srcImage.pixel( currentSrcColInt, 0 );
          px2 = srcImage.pixel( currentSrcColInt + 1, 0 );
          scanLine[x] = curveInterpolation( px1, px2, u, xDerivativeMatrixRed[ currentSrcColInt ], xDerivativeMatrixGreen[ currentSrcColInt ],
                                            xDerivativeMatrixBlue[ currentSrcColInt ], xDerivativeMatrixAlpha[ currentSrcColInt ], xDerivativeMatrixRed[ currentSrcColInt + 1 ], xDerivativeMatrixGreen[ currentSrcColInt + 1 ],
                                            xDerivativeMatrixBlue[ currentSrcColInt + 1 ], xDerivativeMatrixAlpha[ currentSrcColInt + 1 ] );
        }
        else if ( currentSrcRowInt >= ( srcImage.height() - 1 ) )
        {
          int idx = ( srcImage.height() - 1 ) * srcImage.width() + currentSrcColInt;
          px1 = srcImage.pixel( currentSrcColInt, srcImage.height() - 1 );
          px2 = srcImage.pixel( currentSrcColInt + 1, srcImage.height() - 1 );
          scanLine[x] = curveInterpolation( px1, px2, u, xDerivativeMatrixRed[ idx ], xDerivativeMatrixGreen[ idx ], xDerivativeMatrixBlue[idx],
                                            xDerivativeMatrixAlpha[idx], xDerivativeMatrixRed[ idx + 1 ], xDerivativeMatrixGreen[ idx + 1 ], xDerivativeMatrixBlue[idx + 1],
                                            xDerivativeMatrixAlpha[idx + 1] );
        }
        else if ( currentSrcColInt < 0 )
        {
          int idx1 = currentSrcRowInt * srcImage.width();
          int idx2 = idx1 + srcImage.width();
          px1 = srcImage.pixel( 0, currentSrcRowInt );
          px2 = srcImage.pixel( 0, currentSrcRowInt + 1 );
          scanLine[x] = curveInterpolation( px1, px2, v, yDerivativeMatrixRed[ idx1 ], yDerivativeMatrixGreen[ idx1 ], yDerivativeMatrixBlue[ idx1],
                                            yDerivativeMatrixAlpha[ idx1], yDerivativeMatrixRed[ idx2 ], yDerivativeMatrixGreen[ idx2 ], yDerivativeMatrixBlue[ idx2],
                                            yDerivativeMatrixAlpha[ idx2] );
        }
        else if ( currentSrcColInt >= ( srcImage.width() - 1 ) )
        {
          int idx1 = currentSrcRowInt * srcImage.width() + srcImage.width() - 1;
          int idx2 = idx1 + srcImage.width();
          px1 = srcImage.pixel( srcImage.width() - 1, currentSrcRowInt );
          px2 = srcImage.pixel( srcImage.width() - 1, currentSrcRowInt + 1 );
          scanLine[x] = curveInterpolation( px1, px2, v, yDerivativeMatrixRed[ idx1 ], yDerivativeMatrixGreen[ idx1 ], yDerivativeMatrixBlue[ idx1],
                                            yDerivativeMatrixAlpha[ idx1], yDerivativeMatrixRed[ idx2 ], yDerivativeMatrixGreen[ idx2 ], yDerivativeMatrixBlue[ idx2],
                                            yDerivativeMatrixAlpha[ idx2] );
        }
        currentSrcCol += nSrcPerDstX;
        continue;
      }

      //first update the control points if necessary
      if ( currentSrcColInt != lastSrcColInt || currentSrcRowInt != lastSrcRowInt )
      {
        calculateControlPoints( nCols, nRows, currentSrcRowInt, currentSrcColInt, redMatrix, greenMatrix, blueMatrix, alphaMatrix,
                                xDerivativeMatrixRed, xDerivativeMatrixGreen, xDerivativeMatrixBlue, xDerivativeMatrixAlpha,
                                yDerivativeMatrixRed, yDerivativeMatrixGreen, yDerivativeMatrixBlue, yDerivativeMatrixAlpha );
      }

      //bernstein polynomials
      bp0u = calcBernsteinPolyN3( 0, u );
      bp1u = calcBernsteinPolyN3( 1, u );
      bp2u = calcBernsteinPolyN3( 2, u );
      bp3u = calcBernsteinPolyN3( 3, u );
      bp0v = calcBernsteinPolyN3( 0, v );
      bp1v = calcBernsteinPolyN3( 1, v );
      bp2v = calcBernsteinPolyN3( 2, v );
      bp3v = calcBernsteinPolyN3( 3, v );

      //then calculate value based on bernstein form of Bezier patch
      //todo: move into function
      int r = bp0u * bp0v * cRed00 +
              bp1u * bp0v * cRed10 +
              bp2u * bp0v * cRed20 +
              bp3u * bp0v * cRed30 +
              bp0u * bp1v * cRed01 +
              bp1u * bp1v * cRed11 +
              bp2u * bp1v * cRed21 +
              bp3u * bp1v * cRed31 +
              bp0u * bp2v * cRed02 +
              bp1u * bp2v * cRed12 +
              bp2u * bp2v * cRed22 +
              bp3u * bp2v * cRed32 +
              bp0u * bp3v * cRed03 +
              bp1u * bp3v * cRed13 +
              bp2u * bp3v * cRed23 +
              bp3u * bp3v * cRed33;

      int g = bp0u * bp0v * cGreen00 +
              bp1u * bp0v * cGreen10 +
              bp2u * bp0v * cGreen20 +
              bp3u * bp0v * cGreen30 +
              bp0u * bp1v * cGreen01 +
              bp1u * bp1v * cGreen11 +
              bp2u * bp1v * cGreen21 +
              bp3u * bp1v * cGreen31 +
              bp0u * bp2v * cGreen02 +
              bp1u * bp2v * cGreen12 +
              bp2u * bp2v * cGreen22 +
              bp3u * bp2v * cGreen32 +
              bp0u * bp3v * cGreen03 +
              bp1u * bp3v * cGreen13 +
              bp2u * bp3v * cGreen23 +
              bp3u * bp3v * cGreen33;

      int b = bp0u * bp0v * cBlue00 +
              bp1u * bp0v * cBlue10 +
              bp2u * bp0v * cBlue20 +
              bp3u * bp0v * cBlue30 +
              bp0u * bp1v * cBlue01 +
              bp1u * bp1v * cBlue11 +
              bp2u * bp1v * cBlue21 +
              bp3u * bp1v * cBlue31 +
              bp0u * bp2v * cBlue02 +
              bp1u * bp2v * cBlue12 +
              bp2u * bp2v * cBlue22 +
              bp3u * bp2v * cBlue32 +
              bp0u * bp3v * cBlue03 +
              bp1u * bp3v * cBlue13 +
              bp2u * bp3v * cBlue23 +
              bp3u * bp3v * cBlue33;

      int a = bp0u * bp0v * cAlpha00 +
              bp1u * bp0v * cAlpha10 +
              bp2u * bp0v * cAlpha20 +
              bp3u * bp0v * cAlpha30 +
              bp0u * bp1v * cAlpha01 +
              bp1u * bp1v * cAlpha11 +
              bp2u * bp1v * cAlpha21 +
              bp3u * bp1v * cAlpha31 +
              bp0u * bp2v * cAlpha02 +
              bp1u * bp2v * cAlpha12 +
              bp2u * bp2v * cAlpha22 +
              bp3u * bp2v * cAlpha32 +
              bp0u * bp3v * cAlpha03 +
              bp1u * bp3v * cAlpha13 +
              bp2u * bp3v * cAlpha23 +
              bp3u * bp3v * cAlpha33;

      scanLine[x] = createPremultipliedColor( r, g, b, a );

      lastSrcColInt = currentSrcColInt;
      currentSrcCol += nSrcPerDstX;
    }
    lastSrcRowInt = currentSrcRowInt;
    currentSrcRow += nSrcPerDstY;
  }


  //cleanup memory
  delete[] redMatrix;
  delete[] greenMatrix;
  delete[] blueMatrix;
  delete[] alphaMatrix;
  delete[] xDerivativeMatrixRed;
  delete[] xDerivativeMatrixGreen;
  delete[] xDerivativeMatrixBlue;
  delete[] xDerivativeMatrixAlpha;
  delete[] yDerivativeMatrixRed;
  delete[] yDerivativeMatrixGreen;
  delete[] yDerivativeMatrixBlue;
  delete[] yDerivativeMatrixAlpha;
}
Ejemplo n.º 25
0
static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QByteArray &sourceFormat)
{
    QByteArray str;
    QImage image = sourceImage;
    QByteArray format = sourceFormat;

    format = format.left(3);                        // ignore RAW part
    bool gray = format == "pgm";

    if (format == "pbm") {
        image = image.convertToFormat(QImage::Format_Mono);
    } else if (gray) {
        image = image.convertToFormat(QImage::Format_Grayscale8);
    } else {
        switch (image.format()) {
        case QImage::Format_Mono:
        case QImage::Format_MonoLSB:
            image = image.convertToFormat(QImage::Format_Indexed8);
            break;
        case QImage::Format_Indexed8:
        case QImage::Format_RGB32:
        case QImage::Format_ARGB32:
            break;
        default:
            if (image.hasAlphaChannel())
                image = image.convertToFormat(QImage::Format_ARGB32);
            else
                image = image.convertToFormat(QImage::Format_RGB32);
            break;
        }
    }

    if (image.depth() == 1 && image.colorCount() == 2) {
        if (qGray(image.color(0)) < qGray(image.color(1))) {
            // 0=dark/black, 1=light/white - invert
            image.detach();
            for (int y=0; y<image.height(); y++) {
                uchar *p = image.scanLine(y);
                uchar *end = p + image.bytesPerLine();
                while (p < end)
                    *p++ ^= 0xff;
            }
        }
    }

    uint w = image.width();
    uint h = image.height();

    str = "P\n";
    str += QByteArray::number(w);
    str += ' ';
    str += QByteArray::number(h);
    str += '\n';

    switch (image.depth()) {
        case 1: {
            str.insert(1, '4');
            if (out->write(str, str.length()) != str.length())
                return false;
            w = (w+7)/8;
            for (uint y=0; y<h; y++) {
                uchar* line = image.scanLine(y);
                if (w != (uint)out->write((char*)line, w))
                    return false;
            }
            }
            break;

        case 8: {
            str.insert(1, gray ? '5' : '6');
            str.append("255\n");
            if (out->write(str, str.length()) != str.length())
                return false;
            uint bpl = w * (gray ? 1 : 3);
            uchar *buf = new uchar[bpl];
            if (image.format() == QImage::Format_Indexed8) {
                QVector<QRgb> color = image.colorTable();
                for (uint y=0; y<h; y++) {
                    const uchar *b = image.constScanLine(y);
                    uchar *p = buf;
                    uchar *end = buf+bpl;
                    if (gray) {
                        while (p < end) {
                            uchar g = (uchar)qGray(color[*b++]);
                            *p++ = g;
                        }
                    } else {
                        while (p < end) {
                            QRgb rgb = color[*b++];
                            *p++ = qRed(rgb);
                            *p++ = qGreen(rgb);
                            *p++ = qBlue(rgb);
                        }
                    }
                    if (bpl != (uint)out->write((char*)buf, bpl))
                        return false;
                }
            } else {
                for (uint y=0; y<h; y++) {
                    const uchar *b = image.constScanLine(y);
                    uchar *p = buf;
                    uchar *end = buf + bpl;
                    if (gray) {
                        while (p < end)
                            *p++ = *b++;
                    } else {
                        while (p < end) {
                            uchar color = *b++;
                            *p++ = color;
                            *p++ = color;
                            *p++ = color;
                        }
                    }
                    if (bpl != (uint)out->write((char*)buf, bpl))
                        return false;
                }
            }
            delete [] buf;
            break;
        }

        case 32: {
            str.insert(1, '6');
            str.append("255\n");
            if (out->write(str, str.length()) != str.length())
                return false;
            uint bpl = w * 3;
            uchar *buf = new uchar[bpl];
            for (uint y=0; y<h; y++) {
                const QRgb  *b = reinterpret_cast<const QRgb *>(image.constScanLine(y));
                uchar *p = buf;
                uchar *end = buf+bpl;
                while (p < end) {
                    QRgb rgb = *b++;
                    *p++ = qRed(rgb);
                    *p++ = qGreen(rgb);
                    *p++ = qBlue(rgb);
                }
                if (bpl != (uint)out->write((char*)buf, bpl))
                    return false;
            }
            delete [] buf;
            break;
        }

    default:
        return false;
    }

    return true;
}
Ejemplo n.º 26
0
// return average value of fft power iterating over r values
QVector<float> FFT::extract(const QImage &data, const int &x, const int &y) const
{
    // the array created here might be bigger than image size - it has to be
    // a square of side length 2^n
    const int w = mSize.width();
    const int h = mSize.height();
    const int dw = data.width();
    const int dh = data.height();
    ComplexArray *ca = new ComplexArray(boost::extents[w][h]);

    // fill only the data that exists in the image
    for (int ay = 0; ay < h; ay++) {
        int py = (y - h / 2 + ay) + dh;
        while (py >= dh) {
            py -= dh;
        }
        const float wY = mWindow.at(ay);
        #ifdef HAS_IMAGE_CONSTSCANLINE
            const uchar *d = data.constScanLine(py);
        #else
            const uchar *d = data.scanLine(py);
        #endif
        for (int ax = 0; ax < w; ax++) {
            const float wX = mWindow.at(ax);
            int px = (x - w / 2 + ax) + dw;
            while (px >= dw) {
                px -= dw;
            }
            (*ca)[ay][ax] = Complex(d[px] * wX * wY, 0);
        }
    }
    perform(ca);

    float minm = 0;
    float maxm = 0;
    for (int j = 0; j < w; j++) {
        for (int k = 0; k < h; k++) {
            float magnitude = (*ca)[j][k].abs();
            if (magnitude > maxm) {
                maxm = magnitude;
            } else if (magnitude < minm) {
                minm = magnitude;
            }
        }
    }

    float c = 255.0 / log(1.0 + abs(maxm - minm));
    QVector<float> result;
    const int maxR = w / 2;
#ifdef HAS_VECTOR_RESERVE
    result.reserve(maxR);
#endif
    for (int r = 1; r < maxR; r++) {
        int count = 0;
        float sum = 0;
        for (int i = 0; i < 360; i += 5) {
            const int x = r * cos(i) + maxR;
            const int y = r * sin(i) + maxR;
            float p = (*ca)[x][y].abs();
            p = c * log(1.0 + p);
            sum += p;
            count++;
        }
        result.append(sum / count);
    }
    delete ca;

    return result;
}
Ejemplo n.º 27
0
void KisBrush::generateMaskAndApplyMaskOrCreateDab(KisFixedPaintDeviceSP dst,
        ColoringInformation* coloringInformation,
        double scaleX, double scaleY, double angle,
        const KisPaintInformation& info_,
        double subPixelX, double subPixelY, qreal softnessFactor) const
{
    Q_ASSERT(valid());
    Q_UNUSED(info_);
    Q_UNUSED(softnessFactor);

    angle += d->angle;

    // Make sure the angle stay in [0;2*M_PI]
    if (angle < 0) angle += 2 * M_PI;
    if (angle > 2 * M_PI) angle -= 2 * M_PI;
    scaleX *= d->scale;
    scaleY *= d->scale;

    double scale = 0.5 * (scaleX + scaleY);

    prepareBrushPyramid();
    QImage outputImage = d->brushPyramid->createImage(scale, -angle, subPixelX, subPixelY);

    qint32 maskWidth = outputImage.width();
    qint32 maskHeight = outputImage.height();

    dst->setRect(QRect(0, 0, maskWidth, maskHeight));
    dst->initialize();

    quint8* color = 0;

    if (coloringInformation) {
        if (dynamic_cast<PlainColoringInformation*>(coloringInformation)) {
            color = const_cast<quint8*>(coloringInformation->color());
        }
    }

    const KoColorSpace *cs = dst->colorSpace();
    qint32 pixelSize = cs->pixelSize();
    quint8 *dabPointer = dst->data();
    quint8 *rowPointer = dabPointer;
    quint8 *alphaArray = new quint8[maskWidth];
    bool hasColor = this->hasColor();

    for (int y = 0; y < maskHeight; y++) {
#if QT_VERSION >= 0x040700
        const quint8* maskPointer = outputImage.constScanLine(y);
#else
        const quint8* maskPointer = outputImage.scanLine(y);
#endif
        if (coloringInformation) {
            for (int x = 0; x < maskWidth; x++) {
                if (color) {
                    memcpy(dabPointer, color, pixelSize);
                }
                else {
                    memcpy(dabPointer, coloringInformation->color(), pixelSize);
                    coloringInformation->nextColumn();
                }
                dabPointer += pixelSize;
            }
        }

        if (hasColor) {
            const quint8 *src = maskPointer;
            quint8 *dst = alphaArray;
            for (int x = 0; x < maskWidth; x++) {
                const QRgb *c = reinterpret_cast<const QRgb*>(src);

                *dst = KoColorSpaceMaths<quint8>::multiply(255 - qGray(*c), qAlpha(*c));
                src += 4;
                dst++;
            }
        }
        else {
            const quint8 *src = maskPointer;
            quint8 *dst = alphaArray;
            for (int x = 0; x < maskWidth; x++) {
                const QRgb *c = reinterpret_cast<const QRgb*>(src);

                *dst = KoColorSpaceMaths<quint8>::multiply(255 - *src, qAlpha(*c));
                src += 4;
                dst++;
            }
        }

        cs->applyAlphaU8Mask(rowPointer, alphaArray, maskWidth);
        rowPointer += maskWidth * pixelSize;
        dabPointer = rowPointer;

        if (!color && coloringInformation) {
            coloringInformation->nextRow();
        }
    }

    delete alphaArray;
}
Ejemplo n.º 28
0
bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, const QString &description,
                                 int off_x_in, int off_y_in)
{
    QPoint offset = image.offset();
    int off_x = off_x_in + offset.x();
    int off_y = off_y_in + offset.y();

    png_structp png_ptr;
    png_infop info_ptr;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
    if (!png_ptr) {
        return false;
    }

    png_set_error_fn(png_ptr, 0, 0, qt_png_warning);

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr, 0);
        return false;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return false;
    }

    int quality = quality_in;
    if (quality >= 0) {
        if (quality > 9) {
            qWarning("PNG: Quality %d out of range", quality);
            quality = 9;
        }
        png_set_compression_level(png_ptr, quality);
    }

    png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);


    int color_type = 0;
    if (image.colorCount()) {
        if (image.isGrayscale())
            color_type = PNG_COLOR_TYPE_GRAY;
        else
            color_type = PNG_COLOR_TYPE_PALETTE;
    }
    else if (image.format() == QImage::Format_Grayscale8)
        color_type = PNG_COLOR_TYPE_GRAY;
    else if (image.hasAlphaChannel())
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    else
        color_type = PNG_COLOR_TYPE_RGB;

    png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
                 image.depth() == 1 ? 1 : 8, // per channel
                 color_type, 0, 0, 0);       // sets #channels

    if (gamma != 0.0) {
        png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);
    }

    if (image.format() == QImage::Format_MonoLSB)
       png_set_packswap(png_ptr);

    if (color_type == PNG_COLOR_TYPE_PALETTE) {
        // Paletted
        int num_palette = qMin(256, image.colorCount());
        png_color palette[256];
        png_byte trans[256];
        int num_trans = 0;
        for (int i=0; i<num_palette; i++) {
            QRgb rgba=image.color(i);
            palette[i].red = qRed(rgba);
            palette[i].green = qGreen(rgba);
            palette[i].blue = qBlue(rgba);
            trans[i] = qAlpha(rgba);
            if (trans[i] < 255) {
                num_trans = i+1;
            }
        }
        png_set_PLTE(png_ptr, info_ptr, palette, num_palette);

        if (num_trans) {
            png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0);
        }
    }

    // Swap ARGB to RGBA (normal PNG format) before saving on
    // BigEndian machines
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
        png_set_swap_alpha(png_ptr);
    }

    // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless
    if (QSysInfo::ByteOrder == QSysInfo::LittleEndian
        && image.format() != QImage::Format_RGB888) {
        png_set_bgr(png_ptr);
    }

    if (off_x || off_y) {
        png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL);
    }

    if (frames_written > 0)
        png_set_sig_bytes(png_ptr, 8);

    if (image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0) {
        png_set_pHYs(png_ptr, info_ptr,
                image.dotsPerMeterX(), image.dotsPerMeterY(),
                PNG_RESOLUTION_METER);
    }

    set_text(image, png_ptr, info_ptr, description);

    png_write_info(png_ptr, info_ptr);

    if (image.depth() != 1)
        png_set_packing(png_ptr);

    if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888)
        png_set_filler(png_ptr, 0,
            QSysInfo::ByteOrder == QSysInfo::BigEndian ?
                PNG_FILLER_BEFORE : PNG_FILLER_AFTER);

    if (looping >= 0 && frames_written == 0) {
        uchar data[13] = "NETSCAPE2.0";
        //                0123456789aBC
        data[0xB] = looping%0x100;
        data[0xC] = looping/0x100;
        png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13);
    }
    if (ms_delay >= 0 || disposal!=Unspecified) {
        uchar data[4];
        data[0] = disposal;
        data[1] = 0;
        data[2] = (ms_delay/10)/0x100; // hundredths
        data[3] = (ms_delay/10)%0x100;
        png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4);
    }

    int height = image.height();
    int width = image.width();
    switch (image.format()) {
    case QImage::Format_Mono:
    case QImage::Format_MonoLSB:
    case QImage::Format_Indexed8:
    case QImage::Format_Grayscale8:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_RGB888:
        {
            png_bytep* row_pointers = new png_bytep[height];
            for (int y=0; y<height; y++)
                row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y));
            png_write_image(png_ptr, row_pointers);
            delete [] row_pointers;
        }
        break;
    default:
        {
            QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32;
            QImage row;
            png_bytep row_pointers[1];
            for (int y=0; y<height; y++) {
                row = image.copy(0, y, width, 1).convertToFormat(fmt);
                row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));
                png_write_rows(png_ptr, row_pointers, 1);
            }
        }
        break;
    }

    png_write_end(png_ptr, info_ptr);
    frames_written++;

    png_destroy_write_struct(&png_ptr, &info_ptr);

    return true;
}
Ejemplo n.º 29
0
void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subPixelPosition)
{
    QImage mask = textureMapForGlyph(g, subPixelPosition);

#ifdef CACHE_DEBUG
    printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
    if (mask.width() > c.w || mask.height() > c.h) {
        printf("   ERROR; mask is bigger than reserved space! %dx%d instead of %dx%d\n", mask.width(), mask.height(), c.w,c.h);
        return;
    }
#endif

    if (m_format == QFontEngine::Format_A32
        || m_format == QFontEngine::Format_ARGB) {
        QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()),
                   qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(),
                   m_image.format());
        QPainter p(&ref);
        p.setCompositionMode(QPainter::CompositionMode_Source);
        p.fillRect(0, 0, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this
        p.drawImage(0, 0, mask);
        p.end();
    } else if (m_format == QFontEngine::Format_Mono) {
        if (mask.depth() > 1) {
            // TODO optimize this
            mask = mask.alphaChannel();
            mask.invertPixels();
            mask = mask.convertToFormat(QImage::Format_Mono);
        }

        int mw = qMin(mask.width(), c.w);
        int mh = qMin(mask.height(), c.h);
        uchar *d = m_image.bits();
        int dbpl = m_image.bytesPerLine();

        for (int y = 0; y < c.h; ++y) {
            uchar *dest = d + (c.y + y) *dbpl + c.x/8;

            if (y < mh) {
                const uchar *src = mask.constScanLine(y);
                for (int x = 0; x < c.w/8; ++x) {
                    if (x < (mw+7)/8)
                        dest[x] = src[x];
                    else
                        dest[x] = 0;
                }
            } else {
                for (int x = 0; x < c.w/8; ++x)
                    dest[x] = 0;
            }
        }
    } else { // A8
        int mw = qMin(mask.width(), c.w);
        int mh = qMin(mask.height(), c.h);
        uchar *d = m_image.bits();
        int dbpl = m_image.bytesPerLine();

        if (mask.depth() == 1) {
            for (int y = 0; y < c.h; ++y) {
                uchar *dest = d + (c.y + y) *dbpl + c.x;
                if (y < mh) {
                    const uchar *src = mask.constScanLine(y);
                    for (int x = 0; x < c.w; ++x) {
                        if (x < mw)
                            dest[x] = (src[x >> 3] & (1 << (7 - (x & 7)))) > 0 ? 255 : 0;
                    }
                }
            }
        } else if (mask.depth() == 8) {
            for (int y = 0; y < c.h; ++y) {
                uchar *dest = d + (c.y + y) *dbpl + c.x;
                if (y < mh) {
                    const uchar *src = mask.constScanLine(y);
                    for (int x = 0; x < c.w; ++x) {
                        if (x < mw)
                            dest[x] = src[x];
                    }
                }
            }
        }
    }
Ejemplo n.º 30
0
 Q_SLOT void imgSlot(const QImage & img) {
     qDebug() << __FUNCTION__ << name(img.constScanLine(0));
 }