From 797c48f0f74501def9f47444538c0e110fcfcca1 Mon Sep 17 00:00:00 2001 From: Chris Laplante Date: Thu, 26 Feb 2015 00:27:02 -0500 Subject: tdf#84002 Add support for .ase color palettes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CMYK, RGB, and gray color models are supported. LAB colors are replaced by just black since the conversion to RGB is very complicated. Change-Id: I689e6ce972cd7b7f03725f99be4761dea4a81743 Reviewed-on: https://gerrit.libreoffice.org/14661 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl Tested-by: Tomaž Vajngerl --- include/svx/Palette.hxx | 19 +++++ svx/source/tbxctrls/Palette.cxx | 140 +++++++++++++++++++++++++++++++++ svx/source/tbxctrls/PaletteManager.cxx | 2 + 3 files changed, 161 insertions(+) diff --git a/include/svx/Palette.hxx b/include/svx/Palette.hxx index 32088a834e4c..32e00f131716 100644 --- a/include/svx/Palette.hxx +++ b/include/svx/Palette.hxx @@ -40,6 +40,25 @@ public: virtual bool IsValid() = 0; }; +class PaletteASE : public Palette +{ + bool mbValidPalette; + OUString maFName; + OUString maFPath; + OUString maName; + ColorList maColors; + + void LoadPalette(); +public: + PaletteASE( const OUString &rFPath, const OUString &rFName ); + virtual ~PaletteASE(); + + virtual const OUString& GetName() SAL_OVERRIDE; + virtual void LoadColorSet( SvxColorValueSet& rColorSet ) SAL_OVERRIDE; + + virtual bool IsValid() SAL_OVERRIDE; +}; + class PaletteGPL : public Palette { bool mbLoadedPalette; diff --git a/svx/source/tbxctrls/Palette.cxx b/svx/source/tbxctrls/Palette.cxx index e03bed290bc9..e960fbd040f8 100644 --- a/svx/source/tbxctrls/Palette.cxx +++ b/svx/source/tbxctrls/Palette.cxx @@ -24,6 +24,146 @@ Palette::~Palette() { } +PaletteASE::~PaletteASE() +{ +} + +PaletteASE::PaletteASE( const OUString &rFPath, const OUString &rFName ) : + mbValidPalette( false ), + maFName ( rFName ), + maFPath ( rFPath ), + maName ( rFName ) +{ + LoadPalette(); +} + +void PaletteASE::LoadColorSet( SvxColorValueSet& rColorSet ) +{ + rColorSet.Clear(); + int nIx = 1; + for (ColorList::const_iterator it = maColors.begin(); it != maColors.end(); ++it) + { + rColorSet.InsertItem(nIx, it->first, it->second); + ++nIx; + } +} + +const OUString& PaletteASE::GetName() +{ + return maName; +} + +bool PaletteASE::IsValid() +{ + return mbValidPalette; +} + +// CMYK values from 0 to 1 +// TODO: Deduplicate me (taken from core/cui/source/dialogs/colorpicker.cxx) +static void lcl_CMYKtoRGB( float fCyan, float fMagenta, float fYellow, float fKey, float& dR, float& dG, float& dB ) +{ + fCyan = (fCyan * ( 1.0 - fKey )) + fKey; + fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey; + fYellow = (fYellow * ( 1.0 - fKey )) + fKey; + + dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 ); + dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 ); + dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 ); +} + +void PaletteASE::LoadPalette() +{ + SvFileStream aFile(maFPath, StreamMode::READ); + aFile.SetEndian(SvStreamEndian::BIG); + + // Verify magic first 4 characters + sal_Char cMagic[5] = {0}; + if ((aFile.Read(cMagic, 4) != 4) || (strncmp(cMagic, "ASEF", 4) != 0)) + { + mbValidPalette = false; + return; + } + + // Ignore the version number + aFile.SeekRel(4); + + sal_uInt32 nBlocks = 0; + aFile.ReadUInt32(nBlocks); + for (sal_uInt32 nI = 0; nI < nBlocks; nI++) { + sal_uInt32 nChunkType = 0; + aFile.ReadUInt32(nChunkType); + // End chunk + if (nChunkType == 0) + break; + + // Grab chunk size, name length + sal_uInt16 nChunkSize = 0; + sal_uInt16 nChars = 0; + aFile.ReadUInt16(nChunkSize); + aFile.ReadUInt16(nChars); + + OUString aName(""); + if (nChars > 1) + aName = read_uInt16s_ToOUString(aFile, nChars); + else + aFile.SeekRel(2); + + if (nChunkType == 0xC0010000) + { + // Got a start chunk, so set palette name + maName = aName; + // Is there color data? (shouldn't happen in a start block, but check anyway) + if (nChunkSize > ((nChars * 2) + 2)) + aName = ""; + else + continue; + } + + sal_Char cColorModel[5] = {0}; + aFile.Read(cColorModel, 4); + OString aColorModel(cColorModel); + // r, g, and b are floats ranging from 0 to 1 + float r = 0, g = 0, b = 0; + + if (aColorModel.equalsIgnoreAsciiCase("cmyk")) + { + float c = 0, m = 0, y = 0, k = 0; + aFile.ReadFloat(c); + aFile.ReadFloat(m); + aFile.ReadFloat(y); + aFile.ReadFloat(k); + lcl_CMYKtoRGB(c, m, y, k, r, g, b); + } + else if (aColorModel.equalsIgnoreAsciiCase("rgb ")) + { + aFile.ReadFloat(r); + aFile.ReadFloat(g); + aFile.ReadFloat(b); + } + else if (aColorModel.equalsIgnoreAsciiCase("gray")) + { + float nVal = 0; + aFile.ReadFloat(nVal); + r = g = b = nVal; + } + else + { + float nL = 0, nA = 0, nB = 0; + aFile.ReadFloat(nL); + aFile.ReadFloat(nA); + aFile.ReadFloat(nB); + // TODO: How to convert LAB to RGB? + r = g = b = 0; + } + + // Ignore color type + aFile.SeekRel(2); + maColors.push_back(std::make_pair(Color(r * 255, g * 255, b * 255), aName)); + } + + mbValidPalette = true; +} + // PaletteGPL ------------------------------------------------------------------ OString lcl_getToken(const OString& rStr, sal_Int32& index); diff --git a/svx/source/tbxctrls/PaletteManager.cxx b/svx/source/tbxctrls/PaletteManager.cxx index 8d0a21147fe5..ac8e03d11507 100644 --- a/svx/source/tbxctrls/PaletteManager.cxx +++ b/svx/source/tbxctrls/PaletteManager.cxx @@ -67,6 +67,8 @@ void PaletteManager::LoadPalettes() pPalette = new PaletteGPL( aFileStat.getFileURL(), aFName ); else if( aFName.endsWithIgnoreAsciiCase(".soc") ) pPalette = new PaletteSOC( aFileStat.getFileURL(), aFName ); + else if ( aFName.endsWithIgnoreAsciiCase(".ase") ) + pPalette = new PaletteASE( aFileStat.getFileURL(), aFName ); if( pPalette && pPalette->IsValid() ) maPalettes.push_back( pPalette ); -- cgit v1.2.3