LibreOffice Module svx (master)  1
Palette.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <svx/Palette.hxx>
21 #include <tools/stream.hxx>
22 
23 #include <palettes.hxx>
24 
26 {
27 }
28 
30 {
31 }
32 
33 PaletteASE::PaletteASE( const OUString &rFPath, const OUString &rFName ) :
34  mbValidPalette( false ),
35  maFPath ( rFPath ),
36  maASEPaletteName ( rFName )
37 {
38  LoadPalette();
39 }
40 
42 {
43  rColorSet.Clear();
44  int nIx = 1;
45  for (const auto& rColor : maColors)
46  {
47  rColorSet.InsertItem(nIx, rColor.first, rColor.second);
48  ++nIx;
49  }
50 }
51 
52 const OUString& PaletteASE::GetName()
53 {
54  return maASEPaletteName;
55 }
56 
57 const OUString& PaletteASE::GetPath()
58 {
59  return maFPath;
60 }
61 
63 {
64  return mbValidPalette;
65 }
66 
67 // CMYK values from 0 to 1
68 // TODO: Deduplicate me (taken from core/cui/source/dialogs/colorpicker.cxx)
69 static void lcl_CMYKtoRGB( float fCyan, float fMagenta, float fYellow, float fKey, float& dR, float& dG, float& dB )
70 {
71  fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
72  fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
73  fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
74 
75  dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
76  dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
77  dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
78 }
79 
81 {
82  SvFileStream aFile(maFPath, StreamMode::READ);
83  aFile.SetEndian(SvStreamEndian::BIG);
84 
85  // Verify magic first 4 characters
86  char cMagic[5] = {0};
87  if ((aFile.ReadBytes(cMagic, 4) != 4) || (strncmp(cMagic, "ASEF", 4) != 0))
88  {
89  mbValidPalette = false;
90  return;
91  }
92 
93  // Ignore the version number
94  aFile.SeekRel(4);
95 
96  sal_uInt32 nBlocks = 0;
97  aFile.ReadUInt32(nBlocks);
98  for (sal_uInt32 nI = 0; nI < nBlocks; nI++) {
99  sal_uInt32 nChunkType = 0;
100  aFile.ReadUInt32(nChunkType);
101  // End chunk
102  if (nChunkType == 0)
103  break;
104 
105  // Grab chunk size, name length
106  sal_uInt16 nChunkSize = 0;
107  sal_uInt16 nChars = 0;
108  aFile.ReadUInt16(nChunkSize);
109  aFile.ReadUInt16(nChars);
110 
111  OUString aPaletteName("");
112  if (nChars > 1)
113  aPaletteName = read_uInt16s_ToOUString(aFile, nChars);
114  else
115  aFile.SeekRel(2);
116 
117  if (nChunkType == 0xC0010000)
118  {
119  // Got a start chunk, so set palette name
120  maASEPaletteName = aPaletteName;
121  // Is there color data? (shouldn't happen in a start block, but check anyway)
122  if (nChunkSize > ((nChars * 2) + 2))
123  aPaletteName.clear();
124  else
125  continue;
126  }
127 
128  char cColorModel[5] = {0};
129  aFile.ReadBytes(cColorModel, 4);
130  OString aColorModel(cColorModel);
131  // r, g, and b are floats ranging from 0 to 1
132  float r = 0, g = 0, b = 0;
133 
134  if (aColorModel.equalsIgnoreAsciiCase("cmyk"))
135  {
136  float c = 0, m = 0, y = 0, k = 0;
137  aFile.ReadFloat(c);
138  aFile.ReadFloat(m);
139  aFile.ReadFloat(y);
140  aFile.ReadFloat(k);
141  lcl_CMYKtoRGB(c, m, y, k, r, g, b);
142  }
143  else if (aColorModel.equalsIgnoreAsciiCase("rgb "))
144  {
145  aFile.ReadFloat(r);
146  aFile.ReadFloat(g);
147  aFile.ReadFloat(b);
148  }
149  else if (aColorModel.equalsIgnoreAsciiCase("gray"))
150  {
151  float nVal = 0;
152  aFile.ReadFloat(nVal);
153  r = g = b = nVal;
154  }
155  else
156  {
157  float nL = 0, nA = 0, nB = 0;
158  aFile.ReadFloat(nL);
159  aFile.ReadFloat(nA);
160  aFile.ReadFloat(nB);
161  // TODO: How to convert LAB to RGB?
162  r = g = b = 0;
163  }
164 
165  // Ignore color type
166  aFile.SeekRel(2);
167  maColors.emplace_back(Color(r * 255, g * 255, b * 255), aPaletteName);
168  }
169 
170  mbValidPalette = true;
171 }
172 
173 // PaletteGPL ------------------------------------------------------------------
174 
175 static OString lcl_getToken(const OString& rStr, sal_Int32& index);
176 
177 PaletteGPL::PaletteGPL( const OUString &rFPath, const OUString &rFName ) :
178  mbLoadedPalette( false ),
179  mbValidPalette( false ),
180  maFName( rFName ),
181  maFPath( rFPath )
182 {
184 }
185 
187 {
188 }
189 
190 const OUString& PaletteGPL::GetName()
191 {
192  return maGPLPaletteName;
193 }
194 
195 const OUString& PaletteGPL::GetPath()
196 {
197  return maFPath;
198 }
199 
201 {
202  LoadPalette();
203 
204  rColorSet.Clear();
205  int nIx = 1;
206  for (const auto& rColor : maColors)
207  {
208  rColorSet.InsertItem(nIx, rColor.first, rColor.second);
209  ++nIx;
210  }
211 }
212 
214 {
215  return mbValidPalette;
216 }
217 
219 {
220  OString aLine;
221  OString aPaletteName;
222 
223  rFileStream.ReadLine(aLine);
224  if( !aLine.startsWith("GIMP Palette") ) return false;
225  rFileStream.ReadLine(aLine);
226  if( aLine.startsWith("Name: ", &aPaletteName) )
227  {
228  maGPLPaletteName = OStringToOUString(aPaletteName, RTL_TEXTENCODING_ASCII_US);
229  rFileStream.ReadLine(aLine);
230  if( aLine.startsWith("Columns: "))
231  rFileStream.ReadLine(aLine); // we can ignore this
232  }
233  else
234  {
236  }
237  return true;
238 }
239 
241 {
242  SvFileStream aFile(maFPath, StreamMode::READ);
244 }
245 
247 {
248  if( mbLoadedPalette ) return;
249  mbLoadedPalette = true;
250 
251  // TODO add error handling!!!
252  SvFileStream aFile(maFPath, StreamMode::READ);
254 
255  if( !mbValidPalette ) return;
256 
257  OString aLine;
258  do {
259  if (aLine[0] != '#' && aLine[0] != '\n')
260  {
261  // TODO check if r,g,b are 0<= x <=255, or just clamp?
262  sal_Int32 nIndex = 0;
263  OString token;
264 
265  token = lcl_getToken(aLine, nIndex);
266  if(token.isEmpty() || nIndex == -1) continue;
267  sal_Int32 r = token.toInt32();
268 
269  token = lcl_getToken(aLine, nIndex);
270  if(token.isEmpty() || nIndex == -1) continue;
271  sal_Int32 g = token.toInt32();
272 
273  token = lcl_getToken(aLine, nIndex);
274  if(token.isEmpty()) continue;
275  sal_Int32 b = token.toInt32();
276 
277  OString name;
278  if(nIndex != -1)
279  name = aLine.copy(nIndex);
280 
281  maColors.emplace_back(
282  Color(r, g, b),
283  OStringToOUString(name, RTL_TEXTENCODING_ASCII_US));
284  }
285  } while (aFile.ReadLine(aLine));
286 }
287 
288 // finds first token in rStr from index, separated by whitespace
289 // returns position of next token in index
290 static OString lcl_getToken(const OString& rStr, sal_Int32& index)
291 {
292  sal_Int32 substart, toklen = 0;
293  OUString aWhitespaceChars( " \n\t" );
294 
295  while(index < rStr.getLength() &&
296  aWhitespaceChars.indexOf( rStr[index] ) != -1)
297  ++index;
298  if(index == rStr.getLength())
299  {
300  index = -1;
301  return OString();
302  }
303  substart = index;
304 
305  //counts length of token
306  while(index < rStr.getLength() &&
307  aWhitespaceChars.indexOf( rStr[index] ) == -1 )
308  {
309  ++index;
310  ++toklen;
311  }
312 
313  //counts to position of next token
314  while(index < rStr.getLength() &&
315  aWhitespaceChars.indexOf( rStr[index] ) != -1 )
316  ++index;
317  if(index == rStr.getLength())
318  index = -1;
319 
320  return rStr.copy(substart, toklen);
321 }
322 
323 // PaletteSOC ------------------------------------------------------------------
324 
325 PaletteSOC::PaletteSOC( const OUString &rFPath, const OUString &rFName ) :
326  mbLoadedPalette( false ),
327  maFPath( rFPath ),
328  maSOCPaletteName( rFName )
329 {
330 }
331 
333 {
334 }
335 
336 const OUString& PaletteSOC::GetName()
337 {
338  return maSOCPaletteName;
339 }
340 
341 const OUString& PaletteSOC::GetPath()
342 {
343  return maFPath;
344 }
345 
347 {
348  if( !mbLoadedPalette )
349  {
350  mbLoadedPalette = true;
352  (void)mpColorList->Load();
353  }
354  rColorSet.Clear();
355  if( mpColorList.is() )
356  rColorSet.addEntriesForXColorList( *mpColorList );
357 }
358 
360 {
361  return true;
362 }
363 
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void LoadColorSet(SvxColorValueSet &rColorSet) override
Definition: Palette.cxx:200
sal_Int32 nIndex
void LoadPalette()
Definition: Palette.cxx:80
virtual ~Palette()
Definition: Palette.cxx:25
OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nLen)
bool mbLoadedPalette
Definition: palettes.hxx:55
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
virtual const OUString & GetName() override
Definition: Palette.cxx:336
virtual bool IsValid() override
Definition: Palette.cxx:359
PaletteGPL(const OUString &rFPath, const OUString &rFName)
Definition: Palette.cxx:177
OUString maASEPaletteName
Definition: palettes.hxx:36
OUString maFPath
Definition: palettes.hxx:81
void LoadPaletteHeader()
Definition: Palette.cxx:240
OUString maFPath
Definition: palettes.hxx:35
bool mbValidPalette
Definition: palettes.hxx:56
sal_uInt64 SeekRel(sal_Int64 nPos)
void Clear()
virtual bool IsValid() override
Definition: Palette.cxx:62
virtual const OUString & GetName() override
Definition: Palette.cxx:190
virtual void LoadColorSet(SvxColorValueSet &rColorSet) override
Definition: Palette.cxx:346
bool ReadLine(OString &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
bool ReadPaletteHeader(SvFileStream &rFileStream)
Definition: Palette.cxx:218
virtual const OUString & GetPath() override
Definition: Palette.cxx:341
float y
PaletteASE(const OUString &rFPath, const OUString &rFName)
Definition: Palette.cxx:33
virtual const OUString & GetPath() override
Definition: Palette.cxx:195
static XColorListRef AsColorList(rtl::Reference< XPropertyList > const &plist)
Definition: xtable.hxx:386
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
virtual const OUString & GetPath() override
Definition: Palette.cxx:57
static OString lcl_getToken(const OString &rStr, sal_Int32 &index)
Definition: Palette.cxx:290
void LoadPalette()
Definition: Palette.cxx:246
virtual ~PaletteASE() override
Definition: Palette.cxx:29
OUString maSOCPaletteName
Definition: palettes.hxx:82
SvStream & ReadFloat(float &rFloat)
void InsertItem(sal_uInt16 nItemId, const Image &rImage)
bool mbValidPalette
Definition: palettes.hxx:34
ColorList maColors
Definition: palettes.hxx:60
bool mbLoadedPalette
Definition: palettes.hxx:80
virtual const OUString & GetName() override
Definition: Palette.cxx:52
virtual ~PaletteSOC() override
Definition: Palette.cxx:332
virtual ~PaletteGPL() override
Definition: Palette.cxx:186
OUString maFName
Definition: palettes.hxx:57
std::size_t ReadBytes(void *pData, std::size_t nSize)
virtual bool IsValid() override
Definition: Palette.cxx:213
OUString maGPLPaletteName
Definition: palettes.hxx:59
virtual void LoadColorSet(SvxColorValueSet &rColorSet) override
Definition: Palette.cxx:41
void SetEndian(SvStreamEndian SvStreamEndian)
PaletteSOC(const OUString &rFPath, const OUString &rFName)
Definition: Palette.cxx:325
const char * name
void addEntriesForXColorList(const XColorList &rXColorList, sal_uInt32 nStartIndex=1)
XColorListRef mpColorList
Definition: palettes.hxx:83
OUString maFPath
Definition: palettes.hxx:58
tuple m
ColorList maColors
Definition: palettes.hxx:37
static void lcl_CMYKtoRGB(float fCyan, float fMagenta, float fYellow, float fKey, float &dR, float &dG, float &dB)
Definition: Palette.cxx:69
static XPropertyListRef CreatePropertyListFromURL(XPropertyListType t, const OUString &rUrl)
Definition: xtable.cxx:353
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo