static QImage toRgba(const QImage& image, int alpha) { if ( alpha < 0 || alpha >= 255 ) return image; #if QT_VERSION < 0x040000 QImage alphaImage(image.size(), 32); alphaImage.setAlphaBuffer(true); #else QImage alphaImage(image.size(), QImage::Format_ARGB32); #endif const QRgb mask1 = qRgba(0, 0, 0, alpha); const QRgb mask2 = qRgba(255, 255, 255, 0); const QRgb mask3 = qRgba(0, 0, 0, 255); const int w = image.size().width(); const int h = image.size().height(); if ( image.depth() == 8 ) { for ( int y = 0; y < h; y++ ) { QRgb* alphaLine = (QRgb*)alphaImage.scanLine(y); const unsigned char *line = image.scanLine(y); for ( int x = 0; x < w; x++ ) *alphaLine++ = (image.color(*line++) & mask2) | mask1; } } else if ( image.depth() == 32 ) { for ( int y = 0; y < h; y++ ) { QRgb* alphaLine = (QRgb*)alphaImage.scanLine(y); const QRgb* line = (const QRgb*) image.scanLine(y); for ( int x = 0; x < w; x++ ) { const QRgb rgb = *line++; if ( rgb & mask3 ) // alpha != 0 *alphaLine++ = (rgb & mask2) | mask1; else *alphaLine++ = rgb; } } } return alphaImage; }
void Carton::paintFaceReflectionTexture(QPainter *painter, Faces face) { if (m_specularityValue <= 0) return; const Faces emittingFace = face == FrontReflection?Front :face == BackReflection?Back :face == LeftReflection?Left :/* face == RightReflection? */Right; const QSizeF faceSize(this->faceSize(face)); const qreal faceWith = faceSize.width(); const qreal faceHeight = faceSize.height(); const qreal reflectionHeight = faceHeight/100 * m_specularityValue; const qreal remainingFaceHeight = faceHeight - reflectionHeight; QImage blendImage(QSizeF(faceWith, reflectionHeight).toSize(), QImage::Format_ARGB32); QPainter blendPainter(&blendImage); blendPainter.translate(0, -remainingFaceHeight); paintFaceTexture(&blendPainter, emittingFace); blendPainter.end(); QImage alphaImage(QSizeF(faceWith, reflectionHeight).toSize(), QImage::Format_ARGB32); QPainter alphaPainter(&alphaImage); QLinearGradient alphaGradient(0, 0, 0, faceHeight); alphaGradient.setColorAt(0, Qt::black); alphaGradient.setColorAt(1, Qt::lightGray); alphaPainter.setPen(Qt::NoPen); alphaPainter.fillRect(QRectF(0, 0, faceWith, reflectionHeight), alphaGradient); blendImage.setAlphaChannel(alphaImage); alphaPainter.end(); painter->save(); painter->drawImage(0, int(remainingFaceHeight), blendImage); painter->restore(); }
/** * \fn getNextBitmap * \brief Decode a bitmap and store the result (luma only) in the caller supplied vobSubBitmap * @param data (in) Vobsubbitmap to put image in * @param pts Raw pts in 90 Khz Tick * @return 0 on failure, 1 on success * */ uint8_t ADMVideoSubDVB::getNextBitmap(vobSubBitmap *data,uint32_t *pts) { uint8_t *org=NULL; uint32_t packetLen,dts; //,pts; // Clear incoming picture data->clear(); if(!demuxer->readPes(readBuffer,&packetLen, &dts,pts)) return 0; binary->dataLength=packetLen-3; // -2 for stream iD, -1 for ???? if(packetLen<=5) return 1; // And decompress... decoder->uncompress(binary,&sub); // Process All rectangles printf("Found %d rects to process\n",sub.num_rects); for(int i=0;i<sub.num_rects;i++) { AVSubtitleRect *r=&(sub.rects[i]); // First convert RGB to Y+ALPHA for(int col=0;col<r->nb_colors;col++) { // Color is RGB, convert to YUV uint32_t y,u,v,a; uint32_t rgb=r->rgba_palette[col]; y=rgba2y(rgb); u=rgba2u(rgb)&0xff; v=rgba2v(rgb)&0xff; a=_a(rgb); r->rgba_palette[col]=y+(u<<8)+(v<<16)+(a<<24); #if 0 printf("Color %d, alpha %u luma %u rgb:%x\n",col,a,y,rgb); #endif } // Palette is ready, display ! if(r->x>_info.width || r->y>_info.height) { printf("[DVBSUB]Box is outside image\n"); goto _skipX; } #if 0 printf("x :%d\n",r->x); printf("y :%d\n",r->y); printf("w :%d\n",r->w); printf("h :%d\n",r->h); #endif { uint32_t clipW,clipH; clipW=FFMIN(_info.width,r->x+r->w)-r->x; clipH=FFMIN(_info.height,r->y+r->h)-r->y; ADMImage image(r->w,r->h); ADMImage alphaImage(r->w,r->h); uint8_t *ptr=image.data; uint8_t *ptrAlpha=alphaImage.data; uint8_t *in=r->bitmap; for(int yy=0;yy<r->h;yy++) { for(int xx=0;xx<r->w;xx++) { uint32_t alpha,valout; uint32_t val=*in++; val=r->rgba_palette[val]; *ptrAlpha++=(val>>24)&0xff; *ptr++=(val&0xff);; } } // Merge Luma for(int yy=0;yy<clipH;yy++) { org=data->_bitmap+(yy+r->y)*_info.width+r->x; ptrAlpha=alphaImage.data+yy*r->w; ptr=image.data+yy*r->w; int clean=0; for(int xx=0;xx<clipW;xx++) { uint32_t val,before,alpha; //before=*org; val=*ptr++; alpha=*ptrAlpha++; val=val*alpha;//+(255-alpha)*before; val=val>>8; if(val>10) clean=1; // Remove noise *org++=val; } if(clean) data->setDirty(r->y+yy); } } // We dont need chroma here... // Delete palette & data _skipX: av_free(r->rgba_palette); av_free(r->bitmap); } // Next rec.. memset(&sub,0,sizeof(sub)); return 1; }
uint8_t ADMVideoSubDVB::getFrameNumberNoAlloc(uint32_t frame, uint32_t *len, ADMImage *data, uint32_t *flags) { uint8_t *org=NULL; // Read the original PIC if(!_in->getFrameNumberNoAlloc(frame, len, data, flags)) return 0; if(!_inited) { return 0; } // Read the compressed DVB.... uint32_t packetLen,dts,pts; if(!demuxer->readPes(readBuffer,&packetLen, &dts,&pts)) return 1; binary->dataLength=packetLen-3; // -2 for stream iD, -1 for ???? if(packetLen<=5) return 1; // And decompress... decoder->uncompress(binary,&sub); // Process All rectangles printf("Found %d rects to process\n",sub.num_rects); for(int i=0;i<sub.num_rects;i++) { AVSubtitleRect *r=&(sub.rects[i]); // First convert RGB to Y+ALPHA for(int col=0;col<r->nb_colors;col++) { // Color is RGB, convert to YUV uint32_t y,u,v,a; uint32_t rgb=r->rgba_palette[col]; y=rgba2y(rgb); u=rgba2u(rgb)&0xff; v=rgba2v(rgb)&0xff; a=_a(rgb); r->rgba_palette[col]=y+(u<<8)+(v<<16)+(a<<24); printf("Color %d, alpha %u luma %u rgb:%x\n",col,a,y,rgb); } // Palette is ready, display ! if(r->x>_info.width || r->y>_info.height) { printf("[DVBSUB]Box is outside image\n"); goto _skip; } #if 0 printf("x :%d\n",r->x); printf("y :%d\n",r->y); printf("w :%d\n",r->w); printf("h :%d\n",r->h); #endif { uint32_t clipW,clipH; clipW=FFMIN(_info.width,r->x+r->w)-r->x; clipH=FFMIN(_info.height,r->y+r->h)-r->y; ADMImage image(r->w,r->h); ADMImage imageU(r->w,r->h); ADMImage imageV(r->w,r->h); ADMImage alphaImage(r->w,r->h); uint8_t *ptr=image.data; uint8_t *ptrU=imageU.data; uint8_t *ptrV=imageV.data; uint8_t *ptrAlpha=alphaImage.data; uint8_t *in=r->bitmap; for(int yy=0;yy<r->h;yy++) { for(int xx=0;xx<r->w;xx++) { uint32_t alpha,valout; uint32_t val=*in++; val=r->rgba_palette[val]; *ptrAlpha++=(val>>24)&0xff; *ptr++=(val&0xff);; *ptrU++=(val>>8)&0xff; *ptrV++=(val>>16)&0xff; } } // Merge Luma for(int yy=0;yy<clipH;yy++) { org=data->data+(yy+r->y)*_info.width+r->x; ptrAlpha=alphaImage.data+yy*r->w; ptr=image.data+yy*r->w; for(int xx=0;xx<clipW;xx++) { uint32_t val,before,alpha; before=*org; val=*ptr++; alpha=*ptrAlpha++; val=val*alpha+(255-alpha)*before; val>>=8; *org++=val; } } // Shrink alpha & u & v alphaImage.LumaReduceBy2(); imageU.LumaReduceBy2(); imageV.LumaReduceBy2(); r->x>>=1; r->y>>=1; r->w>>=1; r->h>>=1; clipH>>=1; clipW>>=1; uint8_t *orgU=(uint8_t *)(UPLANE(data)+(r->y)*(_info.width>>1)+(r->x)); uint8_t *orgV=(uint8_t *)(VPLANE(data)+(r->y)*(_info.width>>1)+(r->x)); #if 1 // Merge for(int yy=0;yy<clipH;yy++) { ptrAlpha=alphaImage.data+yy*(r->w); ptrU=imageU.data+yy*r->w; ptrV=imageV.data+yy*r->w; for(int xx=0;xx<clipW;xx++) { uint32_t val,valU,valV,before,alpha; uint32_t newU,newV; newU=*ptrU++; newV=*ptrV++; // New color newU=(newU+newV)/2; newV=newU; alpha=*ptrAlpha++; before=*orgU; // old color valU=newU*alpha+(255-alpha)*before; before=*orgV; valV=newV*alpha+(255-alpha)*before; valU=valU>>8; valV=valV>>8; *orgU++=valU; *orgV++=valV; } } #endif } // Delete palette & data _skip: av_free(r->rgba_palette); av_free(r->bitmap); } // Next rec.. memset(&sub,0,sizeof(sub)); return 1; }
QImage QwtPlotRasterItem::compose( const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &imageArea, const QRectF &paintRect, const QSize &imageSize, bool doCache) const { QImage image; if ( imageArea.isEmpty() || paintRect.isEmpty() || imageSize.isEmpty() ) return image; if ( doCache ) { if ( !d_data->cache.image.isNull() && d_data->cache.area == imageArea && d_data->cache.size == paintRect.size() ) { image = d_data->cache.image; } } if ( image.isNull() ) { double dx = 0.0; if ( paintRect.toRect().width() > imageSize.width() ) dx = imageArea.width() / imageSize.width(); const QwtScaleMap xxMap = imageMap(Qt::Horizontal, xMap, imageArea, imageSize, dx); double dy = 0.0; if ( paintRect.toRect().height() > imageSize.height() ) dy = imageArea.height() / imageSize.height(); const QwtScaleMap yyMap = imageMap(Qt::Vertical, yMap, imageArea, imageSize, dy); image = renderImage( xxMap, yyMap, imageArea, imageSize ); if ( doCache ) { d_data->cache.area = imageArea; d_data->cache.size = paintRect.size(); d_data->cache.image = image; } } if ( d_data->alpha >= 0 && d_data->alpha < 255 ) { QImage alphaImage( image.size(), QImage::Format_ARGB32 ); #if QT_VERSION >= 0x040400 && !defined(QT_NO_QFUTURE) uint numThreads = renderThreadCount(); if ( numThreads <= 0 ) numThreads = QThread::idealThreadCount(); if ( numThreads <= 0 ) numThreads = 1; const int numRows = image.height() / numThreads; QList< QFuture<void> > futures; for ( uint i = 0; i < numThreads; i++ ) { QRect tile( 0, i * numRows, image.width(), numRows ); if ( i == numThreads - 1 ) { tile.setHeight( image.height() - i * numRows ); qwtToRgba( &image, &alphaImage, tile, d_data->alpha ); } else { futures += QtConcurrent::run( &qwtToRgba, &image, &alphaImage, tile, d_data->alpha ); } } for ( int i = 0; i < futures.size(); i++ ) futures[i].waitForFinished(); #else const QRect tile( 0, 0, image.width(), image.height() ); qwtToRgba( &image, &alphaImage, tile, d_data->alpha ); #endif image = alphaImage; } return image; }
int main(int argc, char *argv[]) { struct options opts; image_t* img; image_t* mask; parse_arguments(argc, argv, &opts); verbose_level = opts.verbose; img = readImage(opts.infile); if (!img) return EXIT_FAILURE; if (img->color_type != PNG_COLOR_TYPE_RGB) { verbose(1, "Input image must be RGB, 8 bits per channel (or fix the code)\n"); freeImage(img); return EXIT_FAILURE; } if (!img->trans_values) { verbose(2, "%s has no tRNS chunk, assuming transparent black (RBG 0,0,0)\n", opts.infile); img->trans_values = &img->trans_values_buf; } img->num_trans = 0; mask = readImage(opts.maskfile); if (!mask) { freeImage(img); return EXIT_FAILURE; } if (mask->w < img->w || mask->h < img->h) { verbose(1, "Mask image dimensions are smaller than input image\n"); freeImage(img); freeImage(mask); return EXIT_FAILURE; } else if (mask->w != img->w || mask->h != img->h) verbose(2, "Warning: input image and mask have different dimensions\n"); if (mask->color_type != PNG_COLOR_TYPE_GRAY && mask->color_type != PNG_COLOR_TYPE_PALETTE) { verbose(1, "Mask image must be grayscale or paletted (or fix the code)\n"); freeImage(img); freeImage(mask); return EXIT_FAILURE; } if (opts.alpha && (mask->color_type & PNG_COLOR_MASK_PALETTE)) { verbose(2, "Warning: ignoring palette in mask image; using indices\n"); } if (opts.alpha && mask->bit_depth != 8) { verbose(1, "Mask image for the alpha channel must be 8bpp\n"); freeImage(img); freeImage(mask); return EXIT_FAILURE; } if (!opts.alpha && mask->trans) { mask->trans_index = getImageTransIndex(mask); verbose(2, "Using mask image transparency info; trans index %d\n", mask->trans_index); } else if (!opts.alpha) { mask->trans_index = 0; verbose(2, "Mask image has no transparency info; using index %d\n", mask->trans_index); } if (!opts.maskon && !opts.maskoff && !opts.alpha) { freeImage(img); freeImage(mask); verbose(1, "Nothing to do; specify -0 or -1, or use -a\n"); return EXIT_SUCCESS; } if (opts.alpha && (opts.maskon || opts.maskoff)) { verbose(2, "Options -0 and -1 have no effect when -a specified\n"); } if (opts.alpha) alphaImage(img, mask); else maskImage(img, mask, opts.maskon, opts.maskoff); writeImage(img, opts.outfile); freeImage(img); freeImage(mask); return EXIT_SUCCESS; }