bool
YCbCrImageDataSerializer::CopyData(const uint8_t* aYData,
                                   const uint8_t* aCbData, const uint8_t* aCrData,
                                   gfxIntSize aYSize, uint32_t aYStride,
                                   gfxIntSize aCbCrSize, uint32_t aCbCrStride,
                                   uint32_t aYSkip, uint32_t aCbCrSkip)
{
  if (!IsValid() || GetYSize() != aYSize || GetCbCrSize() != aCbCrSize) {
    return false;
  }
  for (int i = 0; i < aYSize.height; ++i) {
    if (aYSkip == 0) {
      // fast path
      memcpy(GetYData() + i * GetYStride(),
             aYData + i * aYStride,
             aYSize.width);
    } else {
      // slower path
      CopyLineWithSkip(aYData + i * aYStride,
                       GetYData() + i * GetYStride(),
                       aYSize.width, aYSkip);
    }
  }
  for (int i = 0; i < aCbCrSize.height; ++i) {
    if (aCbCrSkip == 0) {
      // fast path
      memcpy(GetCbData() + i * GetCbCrStride(),
             aCbData + i * aCbCrStride,
             aCbCrSize.width);
      memcpy(GetCrData() + i * GetCbCrStride(),
             aCrData + i * aCbCrStride,
             aCbCrSize.width);
    } else {
      // slower path
      CopyLineWithSkip(aCbData + i * aCbCrStride,
                       GetCbData() + i * GetCbCrStride(),
                       aCbCrSize.width, aCbCrSkip);
      CopyLineWithSkip(aCrData + i * aCbCrStride,
                       GetCrData() + i * GetCbCrStride(),
                       aCbCrSize.width, aCbCrSkip);
    }
  }
  return true;
}
TemporaryRef<DataSourceSurface>
YCbCrImageDataDeserializer::ToDataSourceSurface()
{
  RefPtr<DataSourceSurface> result =
    Factory::CreateDataSourceSurface(GetYSize(), gfx::SurfaceFormat::B8G8R8X8);

  DataSourceSurface::MappedSurface map;
  result->Map(DataSourceSurface::MapType::WRITE, &map);

  gfx::ConvertYCbCrToRGB32(GetYData(), GetCbData(), GetCrData(),
                           map.mData,
                           0, 0, //pic x and y
                           GetYSize().width, GetYSize().height,
                           GetYStride(), GetCbCrStride(),
                           map.mStride,
                           gfx::YV12);
  result->Unmap();
  return result.forget();
}
already_AddRefed<DataSourceSurface>
YCbCrImageDataDeserializer::ToDataSourceSurface()
{
    RefPtr<DataSourceSurface> result =
        Factory::CreateDataSourceSurface(GetYSize(), gfx::SurfaceFormat::B8G8R8X8);
    if (NS_WARN_IF(!result)) {
        return nullptr;
    }

    DataSourceSurface::MappedSurface map;
    if (NS_WARN_IF(!result->Map(DataSourceSurface::MapType::WRITE, &map))) {
        return nullptr;
    }

    gfx::ConvertYCbCrToRGB32(GetYData(), GetCbData(), GetCrData(),
                             map.mData,
                             0, 0, //pic x and y
                             GetYSize().width, GetYSize().height,
                             GetYStride(), GetCbCrStride(),
                             map.mStride,
                             gfx::YV12);
    result->Unmap();
    return result.forget();
}