void FilterProcessing::SeparateColorChannels(DataSourceSurface* aSource, RefPtr<DataSourceSurface>& aChannel0, RefPtr<DataSourceSurface>& aChannel1, RefPtr<DataSourceSurface>& aChannel2, RefPtr<DataSourceSurface>& aChannel3) { IntSize size = aSource->GetSize(); aChannel0 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); aChannel1 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); aChannel2 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); aChannel3 = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); if (MOZ2D_WARN_IF(!(aChannel0 && aChannel1 && aChannel2 && aChannel3))) { return; } uint8_t* sourceData = aSource->GetData(); int32_t sourceStride = aSource->Stride(); uint8_t* channel0Data = aChannel0->GetData(); uint8_t* channel1Data = aChannel1->GetData(); uint8_t* channel2Data = aChannel2->GetData(); uint8_t* channel3Data = aChannel3->GetData(); int32_t channelStride = aChannel0->Stride(); if (Factory::HasSSE2()) { #ifdef USE_SSE2 SeparateColorChannels_SSE2(size, sourceData, sourceStride, channel0Data, channel1Data, channel2Data, channel3Data, channelStride); #endif } else { SeparateColorChannels_Scalar(size, sourceData, sourceStride, channel0Data, channel1Data, channel2Data, channel3Data, channelStride); } }
TemporaryRef<DataSourceSurface> FilterProcessing::CombineColorChannels(DataSourceSurface* aChannel0, DataSourceSurface* aChannel1, DataSourceSurface* aChannel2, DataSourceSurface* aChannel3) { IntSize size = aChannel0->GetSize(); RefPtr<DataSourceSurface> result = Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8); if (MOZ2D_WARN_IF(!result)) { return nullptr; } int32_t resultStride = result->Stride(); uint8_t* resultData = result->GetData(); int32_t channelStride = aChannel0->Stride(); uint8_t* channel0Data = aChannel0->GetData(); uint8_t* channel1Data = aChannel1->GetData(); uint8_t* channel2Data = aChannel2->GetData(); uint8_t* channel3Data = aChannel3->GetData(); if (Factory::HasSSE2()) { #ifdef USE_SSE2 CombineColorChannels_SSE2(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data); #endif } else { CombineColorChannels_Scalar(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data); } return result.forget(); }
/** * aSrcRect: Rect relative to the aSrc surface * aDestPoint: Point inside aDest surface */ void CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest, IntRect aSrcRect, IntPoint aDestPoint) { if (aSrcRect.Overflows() || IntRect(aDestPoint, aSrcRect.Size()).Overflows()) { MOZ_CRASH("we should never be getting invalid rects at this point"); } MOZ_RELEASE_ASSERT(aSrc->GetFormat() == aDest->GetFormat(), "different surface formats"); MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aSrc->GetSize()).Contains(aSrcRect), "source rect too big for source surface"); MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aDest->GetSize()).Contains(IntRect(aDestPoint, aSrcRect.Size())), "dest surface too small"); if (aSrcRect.IsEmpty()) { return; } DataSourceSurface::ScopedMap srcMap(aSrc, DataSourceSurface::READ); DataSourceSurface::ScopedMap destMap(aDest, DataSourceSurface::WRITE); if (MOZ2D_WARN_IF(!srcMap.IsMapped() || !destMap.IsMapped())) { return; } uint8_t* sourceData = DataAtOffset(aSrc, srcMap.GetMappedSurface(), aSrcRect.TopLeft()); uint32_t sourceStride = srcMap.GetStride(); uint8_t* destData = DataAtOffset(aDest, destMap.GetMappedSurface(), aDestPoint); uint32_t destStride = destMap.GetStride(); if (BytesPerPixel(aSrc->GetFormat()) == 4) { for (int32_t y = 0; y < aSrcRect.height; y++) { PodCopy((int32_t*)destData, (int32_t*)sourceData, aSrcRect.width); sourceData += sourceStride; destData += destStride; } } else if (BytesPerPixel(aSrc->GetFormat()) == 1) { for (int32_t y = 0; y < aSrcRect.height; y++) { PodCopy(destData, sourceData, aSrcRect.width); sourceData += sourceStride; destData += destStride; } } }
TemporaryRef<DataSourceSurface> FilterProcessing::ExtractAlpha(DataSourceSurface* aSource) { IntSize size = aSource->GetSize(); RefPtr<DataSourceSurface> alpha = Factory::CreateDataSourceSurface(size, SurfaceFormat::A8); if (MOZ2D_WARN_IF(!alpha)) { return nullptr; } uint8_t* sourceData = aSource->GetData(); int32_t sourceStride = aSource->Stride(); uint8_t* alphaData = alpha->GetData(); int32_t alphaStride = alpha->Stride(); if (Factory::HasSSE2()) { #ifdef USE_SSE2 ExtractAlpha_SSE2(size, sourceData, sourceStride, alphaData, alphaStride); #endif } else { ExtractAlpha_Scalar(size, sourceData, sourceStride, alphaData, alphaStride); } return alpha.forget(); }