Exemple #1
0
    COR_EXPORT(Image*) CorConvertImage(
      Image* image,
      PixelFormat target_format)
    {
      COR_GUARD("CorConvertImage");

      // if we don't have an image, user doesn't care about format, or
      // the formats match, don't do any conversion.
      if (!image ||
          target_format == PF_DONTCARE ||
          target_format == image->getFormat())
      {
        return image;
      }

      COR_LOG("Doing the conversion...");

      // if we have a palettized image, convert it to a direct color
      // image and then convert that
      if (IsPalettized(image->getFormat())) {
        image = ExpandPalette(image);
      }

      return DirectConversion(image, target_format);
    }
Exemple #2
0
    COR_EXPORT(Image*) CorConvertPalette(
      Image* image,
      PixelFormat palette_format)
    {
      // do we need to convert?
      if (!image ||
          palette_format == PF_DONTCARE ||
          image->getPaletteFormat() == palette_format)
      {
        return image;
      }

      // do we have invalid data?
      if (!IsPalettized(image->getFormat()) ||
          !IsDirect(palette_format))
      {
        delete image;
        return 0;
      }

      const int width  = image->getWidth();
      const int height = image->getHeight();
      const PixelFormat format = image->getFormat();
      const int palette_size = image->getPaletteSize();

      // the palette indices don't change, so just make a copy
      const int image_size = width * height * GetPixelSize(format);
      byte* pixels = new byte[image_size];
      std::memcpy(pixels, image->getPixels(), image_size);

      byte* new_palette = new byte[
        palette_size * GetPixelSize(palette_format)];

      if (!ConvertPixels(new_palette, palette_format,
                         (byte*)image->getPalette(), image->getPaletteFormat(),
                         palette_size))
      {
        delete image;
        delete[] pixels;
        delete[] new_palette;
        return 0;
      }

      delete image;
      return new SimpleImage(
        width, height, format, pixels,
        new_palette, palette_size, palette_format);
    }
//-------------------------------------------------------------------------------------
// Decompression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
{
    if ( !IsCompressed(cImage.format) || IsCompressed(format) )
        return E_INVALIDARG;

    if ( format == DXGI_FORMAT_UNKNOWN )
    {
        // Pick a default decompressed format based on BC input format
        format = _DefaultDecompress( cImage.format );
        if ( format == DXGI_FORMAT_UNKNOWN )
        {
            // Input is not a compressed format
            return E_INVALIDARG;
        }
    }
    else
    {
        if ( !IsValid(format) )
            return E_INVALIDARG;

        if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Create decompressed image
    HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *img = image.GetImage( 0, 0, 0 );
    if ( !img )
    {
        image.Release();
        return E_POINTER;
    }

    // Decompress single image
    hr = _DecompressBC( cImage, *img );
    if ( FAILED(hr) )
        image.Release();

    return hr;
}
//-------------------------------------------------------------------------------------
// Compression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image )
{
    if ( IsCompressed(srcImage.format) || !IsCompressed(format) )
        return E_INVALIDARG;

    if ( IsTypeless(format)
         || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

    // Create compressed image
    HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *img = image.GetImage( 0, 0, 0 );
    if ( !img )
    {
        image.Release();
        return E_POINTER;
    }

    // Compress single image
    if (compress & TEX_COMPRESS_PARALLEL)
    {
#ifndef _OPENMP
        return E_NOTIMPL;
#else
        hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
#endif // _OPENMP
    }
    else
    {
        hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
    }

    if ( FAILED(hr) )
        image.Release();

    return hr;
}
_Use_decl_annotations_
HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata,
                    DXGI_FORMAT format, ScratchImage& images )
{
    if ( !cImages || !nimages )
        return E_INVALIDARG;

    if ( !IsCompressed(metadata.format) || IsCompressed(format) )
        return E_INVALIDARG;

    if ( format == DXGI_FORMAT_UNKNOWN )
    {
        // Pick a default decompressed format based on BC input format
        format = _DefaultDecompress( cImages[0].format );
        if ( format == DXGI_FORMAT_UNKNOWN )
        {
            // Input is not a compressed format
            return E_FAIL;
        }
    }
    else
    {
        if ( !IsValid(format) )
            return E_INVALIDARG;

        if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
            HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    images.Release();

    TexMetadata mdata2 = metadata;
    mdata2.format = format;
    HRESULT hr = images.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != images.GetImageCount() )
    {
        images.Release();
        return E_FAIL;
    }

    const Image* dest = images.GetImages();
    if ( !dest )
    {
        images.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        assert( dest[ index ].format == format );

        const Image& src = cImages[ index ];
        if ( !IsCompressed( src.format ) )
        {
            images.Release();
            return E_FAIL;
        }

        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
        {
            images.Release();
            return E_FAIL;
        }

        hr = _DecompressBC( src, dest[ index ] );
        if ( FAILED(hr) )
        {
            images.Release();
            return hr;
        }
    }

    return S_OK;
}
_Use_decl_annotations_
HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
                  DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages )
{
    if ( !srcImages || !nimages )
        return E_INVALIDARG;

    if ( IsCompressed(metadata.format) || !IsCompressed(format) )
        return E_INVALIDARG;

    if ( IsTypeless(format)
         || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

    cImages.Release();

    TexMetadata mdata2 = metadata;
    mdata2.format = format;
    HRESULT hr = cImages.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != cImages.GetImageCount() )
    {
        cImages.Release();
        return E_FAIL;
    }

    const Image* dest = cImages.GetImages();
    if ( !dest  )
    {
        cImages.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        assert( dest[ index ].format == format );

        const Image& src = srcImages[ index ];

        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
        {
            cImages.Release();
            return E_FAIL;
        }

        if ( (compress & TEX_COMPRESS_PARALLEL) )
        {
#ifndef _OPENMP
            return E_NOTIMPL;
#else
            if ( compress & TEX_COMPRESS_PARALLEL )
            {
                hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
                if ( FAILED(hr) )
                {
                    cImages.Release();
                    return  hr;
                }
            }
#endif // _OPENMP
        }
        else
        {
            hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
            if ( FAILED(hr) )
            {
                cImages.Release();
                return hr;
            }
        }
    }

    return S_OK;
}