uint8_t ADMVideoDeinterlace::getFrameNumberNoAlloc(uint32_t frame,
				uint32_t *len,
   				ADMImage *data,
				uint32_t *flags)
{
//uint8_t *dst,*dstu,*dstv,*srcu,*srcv;
uint32_t uvlen;
		
		if(frame>=_info.nb_frames) return 0;
		
								
		// read uncompressed frame
       		if(!_in->getFrameNumberNoAlloc(frame, len,_uncompressed,flags)) return 0;         	
		
		uvlen=    _info.width*_info.height;
		*len= (uvlen*3)>>1;       			

		// No interleaving detected
		if(!hasMotion(_uncompressed))
           	{
			data->duplicate(_uncompressed);
			
		}
		else
		{
			//printf("Blending\n");
			doBlend(_uncompressed,data);
			memcpy(UPLANE(data),UPLANE(_uncompressed),uvlen>>2);
			memcpy(VPLANE(data),VPLANE(_uncompressed),uvlen>>2);
			data->copyInfo(_uncompressed);
		}
		return 1;
}
Exemplo n.º 2
0
void AutoBlend::init()
{
    // Add widget
    auto toolsWidgetContainer = new QWidget();
    widget = new Ui::AutoBlendWidget();
    widget->setupUi(toolsWidgetContainer);
    widgetProxy = new QGraphicsProxyWidget(this);
    widgetProxy->setWidget(toolsWidgetContainer);

    // Place at bottom left corner
    auto delta = widgetProxy->sceneBoundingRect().bottomLeft() -
    scene()->views().front()->rect().bottomLeft();
    widgetProxy->moveBy(-delta.x(), -delta.y());

    // Fill categories box
    {
        for(auto cat : document->categories.keys()){
            widget->categoriesBox->insertItem(widget->categoriesBox->count(), cat);
        }

        int idx = widget->categoriesBox->findText(document->categoryOf(document->firstModelName()));
        widget->categoriesBox->setCurrentIndex(idx);
    }

    // Create gallery of shapes
    gallery = new Gallery(this, QRectF(0,0,this->bounds.width(), 220));

    // Create container that holds results
    results = new Gallery(this, QRectF(0,0, this->bounds.width(),
                          bounds.height() - gallery->boundingRect().height()),
                          QRectF(0,0,256,256), true);

    results->moveBy(0, gallery->boundingRect().height());

    // Gallery on top of results
    gallery->setZValue(results->zValue() + 10);

    auto dropShadow = new QGraphicsDropShadowEffect();
	dropShadow->setOffset(0, 5);
    dropShadow->setColor(QColor(0, 0, 0, 150));
	dropShadow->setBlurRadius(10);
	gallery->setGraphicsEffect(dropShadow);

	// Connect UI with actions
	{
		connect(widget->categoriesBox, &QComboBox::currentTextChanged, [&](QString text){
			document->currentCategory = text;
		});

        connect(widget->analyzeButton, &QPushButton::pressed, [&](){
            document->computePairwise(widget->categoriesBox->currentText());
		});

		// Default view angle
		{
			// Camera target and initial position
			auto camera = new Eigen::Camera();
			auto frame = camera->frame();
			frame.position = Eigen::Vector3f(-1, 0, 0.5);
			camera->setTarget(Eigen::Vector3f(0, 0, 0.5));
            camera->setFrame(frame);

            int deltaZoom = document->extent().length() * 1.0;

            // Default view angle
            double theta1 = acos(-1) * 0.75;
            double theta2 = acos(-1) * 0.10;
            camera->rotateAroundTarget(Eigen::Quaternionf(Eigen::AngleAxisf(theta1, Eigen::Vector3f::UnitY())));
            camera->zoom(-(4+deltaZoom));
            camera->rotateAroundTarget(Eigen::Quaternionf(Eigen::AngleAxisf(theta2, Eigen::Vector3f::UnitX())));
			auto cp = camera->position();
			cameraPos = QVector3D(cp[0], cp[1], cp[2]);

			// Camera settings
			camera->setViewport(128, 128);
			Eigen::Matrix4f p = camera->projectionMatrix();
			Eigen::Matrix4f v = camera->viewMatrix().matrix();
			p.transposeInPlace();
			v.transposeInPlace();
			cameraMatrix = QMatrix4x4(p.data()) * QMatrix4x4(v.data());
        }

		connect(document, &Document::categoryAnalysisDone, [=](){
			if (gallery == nullptr) return;

			// Fill gallery
			gallery->clearThumbnails();

			auto catModels = document->categories[document->currentCategory].toStringList();
			for (auto targetName : catModels)
			{
				auto targetModel = document->cacheModel(targetName);
				auto t = gallery->addTextItem(targetName);

				QVariantMap data = t->data;
				data["targetName"].setValue(targetName);
				t->setData(data);

				t->setCamera(cameraPos, cameraMatrix);
				t->setFlag(QGraphicsItem::ItemIsSelectable);

				// Add parts of target shape
				for (auto n : targetModel->nodes){
					t->addAuxMesh(toBasicMesh(targetModel->getMesh(n->id), n->vis_property["color"].value<QColor>()));
				}

                scene()->update(t->sceneBoundingRect());
            }

            scene()->update(this->sceneBoundingRect());
            QTimer::singleShot(500, [=]{ gallery->update(); });
		});

		// Do blend
		connect(widget->blendButton, SIGNAL(pressed()), SLOT(doBlend())); 
    }
}
uint8_t ADMVideoTelecide::getFrameNumberNoAlloc(uint32_t frame,
			uint32_t *len,
			ADMImage *data,
			uint32_t *flags)
{
uint32_t uvlen;
uint32_t dummylen;
uint8_t motion;

uint32_t 	cmatch,nmatch,n2match;
ADMImage	*cur,*next;

			
		if(frame>=_info.nb_frames) return 0;			
		uvlen=    _info.width*_info.height;
		*len=uvlen+(uvlen>>1);
		
		cur=vidCache->getImage(frame);
		if(!cur) return 0;
		data->copyInfo(cur);
		if(!frame || frame==_info.nb_frames-1)
		{

			data->duplicate(cur);
			vidCache->unlockAll();
			return 1;
		
		}
		
		next=vidCache->getImage(frame-1);
		if(!next) 
		{
			vidCache->unlockAll();
			return 0;
		}		
		

		// for u & v , no action -> copy it as is
		memcpy(UPLANE(data),UPLANE(cur),uvlen>>2);
		memcpy(VPLANE(data),VPLANE(cur),uvlen>>2);
		data->copyInfo(cur);

        	// No interleaving detected
           	if(!(motion=hasMotion(data)) )
		{
			printf("\n Not interlaced !\n");
			memcpy(YPLANE(data),YPLANE(cur),uvlen);
			vidCache->unlockAll();
      			return 1; // over !
		}
		// else cmatch is the current match
		cmatch=getMatch(cur);

/*	------------------------------------------------------------------------------------
			Try to complete with next frame  fields
-----------------------------------------------------------------------------------
*/
		// Interleav next in even field
		
		interleave(cur,_uncompressed,1);
		interleave(next,_uncompressed,0);
		nmatch=getMatch(_uncompressed);
		
		interleave(cur,_uncompressed,0);
		interleave(next,_uncompressed,1);
		n2match=getMatch(_uncompressed);

		printf(" Cur  : %lu \n",cmatch);
		printf(" Next : %lu \n",nmatch);
		printf(" NextP: %lu \n",n2match);

		if((cmatch<nmatch)&&(cmatch<n2match))
		{
			printf("\n __ pure interlaced __\n");
			interleave(cur,_uncompressed,0);
			interleave(cur,_uncompressed,1);
			hasMotion(_uncompressed);
	  		doBlend(_uncompressed,data);			
			vidCache->unlockAll();
			return 1;
		}
		if( nmatch > n2match)
		{
			printf("\n -------Shifted-P is better \n");	
			if(hasMotion(_uncompressed))
			{
				 doBlend(_uncompressed,data);
				 printf(" but there is still motion \n");
			}
			else
				data->duplicate(_uncompressed);

		}
		else
		{
			printf("\n -------Shifted-O is better \n");
			interleave(cur,_uncompressed,1);
			interleave(next,_uncompressed,0);
			if(hasMotion(_uncompressed))
			{
				 doBlend(_uncompressed,data);
				 printf(" but there is still motion \n");
			}
			else
				data->duplicate(_uncompressed);
		}
		// which chroma is better ? from current or from next ?
		// search for a transition and see if there is also one ?
		vidCache->unlockAll();				
		return 1;						
}
Exemplo n.º 4
0
void blend(TToonzImageP ti, TRasterPT<PIXEL> rasOut,
           const std::vector<BlendParam> &params) {
  assert(ti->getRaster()->getSize() == rasOut->getSize());

  // Extract the interesting raster. It should be the savebox of passed cmap,
  // plus - if
  // some param has the 0 index as blending color - the intensity of that blend
  // param.
  unsigned int i, j;
  TRect saveBox(ti->getSavebox());

  int enlargement = 0;
  for (i = 0; i < params.size(); ++i)
    for (j = 0; j < params[i].colorsIndexes.size(); ++j)
      if (params[i].colorsIndexes[j] == 0)
        enlargement = std::max(enlargement, tceil(params[i].intensity));
  saveBox           = saveBox.enlarge(enlargement);

  TRasterCM32P cmIn(ti->getRaster()->extract(saveBox));
  TRasterPT<PIXEL> rasOutExtract = rasOut->extract(saveBox);

  // Ensure that cmIn and rasOut have the same size
  unsigned int lx = cmIn->getLx(), ly = cmIn->getLy();

  // Build the pure colors infos
  SelectionRaster selectionRaster(cmIn);

  // Now, build a little group of BlurPatterns - and for each, one for passed
  // param.
  // A small number of patterns per param is needed to make the pattern look not
  // ever the same.
  const int blurPatternsPerParam = 10;
  std::vector<BlurPatternContainer> blurGroup(params.size());

  for (i = 0; i < params.size(); ++i) {
    BlurPatternContainer &blurContainer = blurGroup[i];
    blurContainer.reserve(blurPatternsPerParam);

    for (j = 0; j < blurPatternsPerParam; ++j)
      blurContainer.push_back(BlurPattern(
          params[i].intensity, params[i].smoothness, params[i].stopAtCountour));
  }

  // Build the palette
  TPalette *palette = ti->getPalette();
  std::vector<TPixel32> paletteColors;
  paletteColors.resize(palette->getStyleCount());
  for (i             = 0; i < paletteColors.size(); ++i)
    paletteColors[i] = premultiply(palette->getStyle(i)->getAverageColor());

  // Build the 4 auxiliary rasters for the blending procedure: they are ink /
  // paint versus input / output in the blend.
  // The output raster is reused to spare some memory - it should be, say, the
  // inkLayer's second at the end of the overall
  // blending procedure. It could be the first, without the necessity of
  // clearing it before blending the layers, but things
  // get more complicated when PIXEL is TPixel64...
  RGBMRasterPair inkLayer, paintLayer;

  TRaster32P rasOut32P_1(lx, ly, lx, (TPixel32 *)rasOut->getRawData(), false);
  inkLayer.first  = (params.size() % 2) ? rasOut32P_1 : TRaster32P(lx, ly);
  inkLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_1;

  if (PIXEL::maxChannelValue >= TPixel64::maxChannelValue) {
    TRaster32P rasOut32P_2(lx, ly, lx,
                           ((TPixel32 *)rasOut->getRawData()) + lx * ly, false);
    paintLayer.first  = (params.size() % 2) ? rasOut32P_2 : TRaster32P(lx, ly);
    paintLayer.second = (params.size() % 2) ? TRaster32P(lx, ly) : rasOut32P_2;
  } else {
    paintLayer.first  = TRaster32P(lx, ly);
    paintLayer.second = TRaster32P(lx, ly);
  }

  inkLayer.first->clear();
  inkLayer.second->clear();
  paintLayer.first->clear();
  paintLayer.second->clear();

  // Now, we have to perform the blur of each of the cm's pixels.
  cmIn->lock();
  rasOut->lock();

  inkLayer.first->lock();
  inkLayer.second->lock();
  paintLayer.first->lock();
  paintLayer.second->lock();

  // Convert the initial cmIn to fullcolor ink - paint layers
  buildLayers(cmIn, paletteColors, inkLayer.first, paintLayer.first);

  // Perform the blend on separated ink - paint layers
  for (i = 0; i < params.size(); ++i) {
    if (params[i].colorsIndexes.size() == 0) continue;

    selectionRaster.updateSelection(cmIn, params[i]);
    doBlend(cmIn, inkLayer, paintLayer, selectionRaster, blurGroup[i]);

    tswap(inkLayer.first, inkLayer.second);
    tswap(paintLayer.first, paintLayer.second);
  }

  // Release the unnecessary rasters
  inkLayer.second->unlock();
  paintLayer.second->unlock();
  inkLayer.second   = TRaster32P();
  paintLayer.second = TRaster32P();

  // Clear rasOut - since it was reused to spare space...
  rasOut->clear();

  // Add the ink & paint layers on the output raster
  double PIXELmaxChannelValue = PIXEL::maxChannelValue;
  double toPIXELFactor =
      PIXELmaxChannelValue / (double)TPixel32::maxChannelValue;
  double inkFactor, paintFactor;
  TPoint pos;

  PIXEL *outPix, *outBegin    = (PIXEL *)rasOutExtract->getRawData();
  TPixelCM32 *cmPix, *cmBegin = (TPixelCM32 *)cmIn->getRawData();
  int wrap = rasOutExtract->getWrap();

  TPixel32 *inkPix   = (TPixel32 *)inkLayer.first->getRawData();
  TPixel32 *paintPix = (TPixel32 *)paintLayer.first->getRawData();

  for (i = 0; i < ly; ++i) {
    outPix = outBegin + wrap * i;
    cmPix  = cmBegin + wrap * i;
    for (j = 0; j < lx; ++j, ++outPix, ++cmPix, ++inkPix, ++paintPix) {
      getFactors(cmPix->getTone(), inkFactor, paintFactor);

      outPix->r = tcrop(
          toPIXELFactor * (inkFactor * inkPix->r + paintFactor * paintPix->r),
          0.0, PIXELmaxChannelValue);
      outPix->g = tcrop(
          toPIXELFactor * (inkFactor * inkPix->g + paintFactor * paintPix->g),
          0.0, PIXELmaxChannelValue);
      outPix->b = tcrop(
          toPIXELFactor * (inkFactor * inkPix->b + paintFactor * paintPix->b),
          0.0, PIXELmaxChannelValue);
      outPix->m = tcrop(
          toPIXELFactor * (inkFactor * inkPix->m + paintFactor * paintPix->m),
          0.0, PIXELmaxChannelValue);
    }
  }

  inkLayer.first->unlock();
  paintLayer.first->unlock();

  cmIn->unlock();
  rasOut->unlock();

  // Destroy the auxiliary bitmaps
  selectionRaster.destroy();
}
uint8_t ADMVideoTelecide::getFrameNumberNoAlloc(uint32_t frame,
																	uint32_t *len,
   																	uint8_t *data,
   																	uint32_t *flags)
{
uint32_t uvlen;
uint32_t dummylen;
uint8_t motion;

uint32_t 	cmatch,nmatch,n2match;

			

			assert(frame<_info.nb_frames);
			assert(_uncompressed);					
			
			uvlen=    _info.width*_info.height;
			*len=uvlen+(uvlen>>1);
			
			if(_instock!=frame)
			{																	
			// read uncompressed frame
       		if(!_in->getFrameNumberNoAlloc(frame, &dummylen,_uncompressed,flags)) return 0;         	
   		}
     	else
      {
					memcpy(_uncompressed,_next,*len);
			}

           // for u & v , no action -> copy it as is
           memcpy(data,_uncompressed,(uvlen*3)>>1);
	
    	     if(frame==_info.nb_frames-1) return 1;

           // No interleaving detected
           if(!(motion=hasMotion()) )
           	{
									printf("\n Not interlaced !\n");
      						return 1; // over !					
             }
            cmatch=getMatch();

    /*	------------------------------------------------------------------------------------
								Try to complete with next frame  fields
	------------------------------------------------------------------------------------
					*/
            if(!_in->getFrameNumberNoAlloc(frame+1, &dummylen,_next,flags)) return 0;
            _instock=frame+1;
						interleave(_next,0);

						nmatch=getMatch();
						
					  memcpy(_uncompressed,data,_info.width*_info.height);
	          interleave(_next,1);
	          
 						n2match=getMatch();

						printf(" Cur  : %lu \n",cmatch);
						printf(" Next : %lu \n",nmatch);
						printf(" NextP: %lu \n",n2match);

						if((cmatch<nmatch)&&(cmatch<n2match))
						{
			   				printf("\n __ pure interlaced __\n");
			          memcpy(_uncompressed,data,_info.width*_info.height);
								hasMotion();
	  		        doBlend(data);					
								return 1;
						}
						if( nmatch > n2match)
						{
							printf("\n -------Shifted-P is better \n");
							if(hasMotion())
							{
								 doBlend(data);
								 printf(" but there is still motion \n");
							}
						}
						else
						{
							printf("\n -------Shifted-O is better \n");
							memcpy(_uncompressed,data,_info.width*_info.height);
	          	interleave(_next,0);
							if(hasMotion())
							{
								 doBlend(data);
								 printf(" but there is still motion \n");
							}
						}							  		    			
						// which chroma is better ? from current or from next ?
						// search for a transition and see if there is also one ?
						
						return 1;						
}