Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: MiraMonRaster driver
4 : * Purpose: Implements MMRPalettes class: handles access to a DBF file
5 : * containing color information, which is then converted into
6 : * either a color table or an attribute table, depending on the
7 : * context.
8 : * Author: Abel Pau
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 2025, Xavier Pons
12 : *
13 : * SPDX-License-Identifier: MIT
14 : ****************************************************************************/
15 :
16 : #include "miramon_rel.h"
17 : #include "miramon_palettes.h"
18 :
19 : #include "../miramon_common/mm_gdal_functions.h" // For MMCheck_REL_FILE()
20 :
21 62 : MMRPalettes::MMRPalettes(MMRRel &fRel, int nIBand) : m_pfRel(&fRel)
22 : {
23 : // Is the palette a constant color? Then, which color is it?
24 62 : MMRBand *poBand = m_pfRel->GetBand(nIBand - 1);
25 62 : if (poBand == nullptr)
26 40 : return;
27 :
28 62 : m_osBandSection = poBand->GetBandSection();
29 :
30 62 : if (EQUAL(poBand->GetColor_Const(), "1"))
31 : {
32 1 : m_bIsConstantColor = true;
33 1 : if (!poBand->ValidConstantColorRGB())
34 0 : return; // The constant color indicated is wrong
35 :
36 1 : SetConstantColorRGB(poBand->GetConstantColorRGB());
37 1 : m_nRealNPaletteColors = 1;
38 1 : m_bIsValid = true;
39 1 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
40 1 : SetIsCategorical(true);
41 1 : return;
42 : }
43 :
44 : // Is this an authomatic palette or has a color table (dbf, pal,...)?
45 151 : if (EQUAL(poBand->GetColor_Paleta(), "<Automatic>") ||
46 90 : poBand->GetColor_Paleta().empty())
47 36 : m_bIsAutomatic = true;
48 :
49 : // Treatment of the color variable
50 61 : if (poBand->GetColor_TractamentVariable().empty())
51 : {
52 31 : if (poBand->IsCategorical())
53 25 : SetIsCategorical(true);
54 : else
55 6 : SetIsCategorical(false);
56 : }
57 : else
58 : {
59 30 : if (EQUAL(poBand->GetColor_TractamentVariable(), "Categoric"))
60 25 : SetIsCategorical(true);
61 : else
62 5 : SetIsCategorical(false);
63 : }
64 :
65 61 : if (UpdateColorInfo() == CE_Failure)
66 0 : return;
67 :
68 61 : if (m_bIsAutomatic)
69 : {
70 : // How many "colors" are involved?
71 72 : CPLString os_Color_N_SimbolsALaTaula = "";
72 36 : if (!poBand->GetColor_N_SimbolsALaTaula().empty())
73 : {
74 0 : GIntBig nBigVal = CPLAtoGIntBig(os_Color_N_SimbolsALaTaula);
75 0 : if (nBigVal >= INT_MAX)
76 0 : return;
77 0 : m_nRealNPaletteColors = m_nNPaletteColors =
78 : static_cast<int>(nBigVal);
79 0 : if (m_nNPaletteColors <= 0 || m_nNPaletteColors >= 256)
80 : {
81 0 : CPLError(CE_Failure, CPLE_AssertionFailed,
82 : "Invalid number of colors "
83 : "(Color_N_SimbolsALaTaula) in \"%s\".",
84 0 : m_pfRel->GetRELName().c_str());
85 0 : return;
86 : }
87 : }
88 : else
89 : {
90 36 : if (IsCategorical())
91 : {
92 : // Predefined color table: m_ThematicPalette
93 32 : if (CE_None != GetPaletteColors_Automatic())
94 0 : return;
95 : }
96 : else // No palette associated
97 4 : return;
98 : }
99 32 : m_bIsValid = true;
100 32 : return;
101 : }
102 :
103 : // If color is no automatic, from where we got this?
104 50 : CPLString osExtension = CPLGetExtensionSafe(poBand->GetColor_Paleta());
105 25 : if (osExtension.tolower() == "dbf")
106 : {
107 22 : if (CE_None != GetPaletteColors_DBF(poBand->GetColor_Paleta()))
108 3 : return;
109 :
110 19 : m_bIsValid = true;
111 : }
112 4 : else if (osExtension.tolower() == "pal" || osExtension.tolower() == "p25" ||
113 1 : osExtension.tolower() == "p65")
114 : {
115 3 : if (CE_None != GetPaletteColors_PAL_P25_P65(poBand->GetColor_Paleta()))
116 0 : return;
117 :
118 3 : m_bIsValid = true;
119 : }
120 : else
121 0 : return;
122 :
123 22 : m_nRealNPaletteColors = m_nNPaletteColors;
124 22 : if (HasNodata())
125 : {
126 6 : if (m_nNPaletteColors < 1)
127 0 : return;
128 6 : m_nNPaletteColors--;
129 : }
130 : else
131 : {
132 : // If palette doesn't have nodata let's set some index
133 16 : m_nNoDataPaletteIndex = m_nRealNPaletteColors;
134 : }
135 : }
136 :
137 62 : MMRPalettes::~MMRPalettes()
138 : {
139 62 : }
140 :
141 1201 : void MMRPalettes::AssignColorFromDBF(struct MM_DATA_BASE_XP &oColorTable,
142 : char *pzsRecord, char *pszField,
143 : MM_EXT_DBF_N_FIELDS &nRIndex,
144 : MM_EXT_DBF_N_FIELDS &nGIndex,
145 : MM_EXT_DBF_N_FIELDS &nBIndex,
146 : int nIPaletteIndex)
147 : {
148 : // RED
149 1201 : memcpy(pszField, pzsRecord + oColorTable.pField[nRIndex].AccumulatedBytes,
150 1201 : oColorTable.pField[nRIndex].BytesPerField);
151 1201 : pszField[oColorTable.pField[nRIndex].BytesPerField] = '\0';
152 1201 : m_aadfPaletteColors[0][nIPaletteIndex] = CPLAtof(pszField);
153 :
154 : // GREEN
155 1201 : memcpy(pszField, pzsRecord + oColorTable.pField[nGIndex].AccumulatedBytes,
156 1201 : oColorTable.pField[nGIndex].BytesPerField);
157 1201 : pszField[oColorTable.pField[nGIndex].BytesPerField] = '\0';
158 1201 : m_aadfPaletteColors[1][nIPaletteIndex] = CPLAtof(pszField);
159 :
160 : // BLUE
161 1201 : memcpy(pszField, pzsRecord + oColorTable.pField[nBIndex].AccumulatedBytes,
162 1201 : oColorTable.pField[nBIndex].BytesPerField);
163 1201 : pszField[oColorTable.pField[nBIndex].BytesPerField] = '\0';
164 1201 : m_aadfPaletteColors[2][nIPaletteIndex] = CPLAtof(pszField);
165 :
166 : // ALPHA
167 1201 : if (m_aadfPaletteColors[0][nIPaletteIndex] == -1 &&
168 1206 : m_aadfPaletteColors[1][nIPaletteIndex] == -1 &&
169 5 : m_aadfPaletteColors[2][nIPaletteIndex] == -1)
170 : {
171 : // Transparent (white or whatever color)
172 5 : m_aadfPaletteColors[0][nIPaletteIndex] = m_sNoDataColorRGB.c1;
173 5 : m_aadfPaletteColors[1][nIPaletteIndex] = m_sNoDataColorRGB.c2;
174 5 : m_aadfPaletteColors[2][nIPaletteIndex] = m_sNoDataColorRGB.c3;
175 5 : m_aadfPaletteColors[3][nIPaletteIndex] = m_sNoDataColorRGB.c4;
176 : }
177 : else
178 1196 : m_aadfPaletteColors[3][nIPaletteIndex] = 255;
179 1201 : }
180 :
181 21 : CPLErr MMRPalettes::GetPaletteColors_DBF_Indexes(
182 : struct MM_DATA_BASE_XP &oColorTable, MM_EXT_DBF_N_FIELDS &nClauSimbol,
183 : MM_EXT_DBF_N_FIELDS &nRIndex, MM_EXT_DBF_N_FIELDS &nGIndex,
184 : MM_EXT_DBF_N_FIELDS &nBIndex)
185 : {
186 21 : nClauSimbol = oColorTable.nFields;
187 21 : nRIndex = oColorTable.nFields;
188 21 : nGIndex = oColorTable.nFields;
189 21 : nBIndex = oColorTable.nFields;
190 :
191 111 : for (MM_EXT_DBF_N_FIELDS nIField = 0; nIField < oColorTable.nFields;
192 : nIField++)
193 : {
194 90 : if (EQUAL(oColorTable.pField[nIField].FieldName, "CLAUSIMBOL"))
195 20 : nClauSimbol = nIField;
196 70 : else if (EQUAL(oColorTable.pField[nIField].FieldName, "R_COLOR"))
197 21 : nRIndex = nIField;
198 49 : else if (EQUAL(oColorTable.pField[nIField].FieldName, "G_COLOR"))
199 21 : nGIndex = nIField;
200 28 : else if (EQUAL(oColorTable.pField[nIField].FieldName, "B_COLOR"))
201 21 : nBIndex = nIField;
202 : }
203 :
204 21 : if (nClauSimbol == oColorTable.nFields || nRIndex == oColorTable.nFields ||
205 20 : nGIndex == oColorTable.nFields || nBIndex == oColorTable.nFields)
206 1 : return CE_Failure;
207 :
208 20 : return CE_None;
209 : }
210 :
211 : // Colors in a PAL, P25 or P65 format files
212 : // Updates nNPaletteColors
213 32 : CPLErr MMRPalettes::GetPaletteColors_Automatic()
214 : {
215 32 : m_nRealNPaletteColors = m_nNPaletteColors =
216 32 : static_cast<int>(m_ThematicPalette.size());
217 :
218 160 : for (int iColumn = 0; iColumn < 4; iColumn++)
219 : {
220 : try
221 : {
222 128 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
223 : }
224 0 : catch (std::bad_alloc &e)
225 : {
226 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
227 0 : return CE_Failure;
228 : }
229 : }
230 :
231 8224 : for (int nIndex = 0; nIndex < m_nRealNPaletteColors; nIndex++)
232 : {
233 : // Index of the color
234 :
235 : // RED
236 8192 : m_aadfPaletteColors[0][nIndex] = m_ThematicPalette[nIndex].c1;
237 :
238 : // GREEN
239 8192 : m_aadfPaletteColors[1][nIndex] = m_ThematicPalette[nIndex].c2;
240 :
241 : // BLUE
242 8192 : m_aadfPaletteColors[2][nIndex] = m_ThematicPalette[nIndex].c3;
243 :
244 : // ALPHA
245 8192 : m_aadfPaletteColors[3][nIndex] = m_ThematicPalette[nIndex].c4;
246 : }
247 :
248 32 : return CE_None;
249 : }
250 :
251 : // Updates nNPaletteColors
252 22 : CPLErr MMRPalettes::GetPaletteColors_DBF(const CPLString &os_Color_Paleta_DBF)
253 :
254 : {
255 : // Getting the full path name of the DBF
256 44 : CPLString osAux = CPLGetPathSafe(m_pfRel->GetRELNameChar());
257 : CPLString osColorTableFileName =
258 44 : CPLFormFilenameSafe(osAux.c_str(), os_Color_Paleta_DBF.c_str(), "");
259 :
260 : // Reading the DBF file
261 : struct MM_DATA_BASE_XP oColorTable;
262 22 : memset(&oColorTable, 0, sizeof(oColorTable));
263 :
264 22 : if (MM_ReadExtendedDBFHeaderFromFile(osColorTableFileName.c_str(),
265 : &oColorTable,
266 44 : m_pfRel->GetRELNameChar()))
267 : {
268 1 : CPLError(CE_Failure, CPLE_AssertionFailed,
269 : "Invalid color table:"
270 : "\"%s\".",
271 : osColorTableFileName.c_str());
272 :
273 1 : return CE_Failure;
274 : }
275 :
276 : // Getting indices of fields that determine the colors.
277 : MM_EXT_DBF_N_FIELDS nClauSimbol, nRIndex, nGIndex, nBIndex;
278 21 : if (CE_Failure == GetPaletteColors_DBF_Indexes(oColorTable, nClauSimbol,
279 : nRIndex, nGIndex, nBIndex))
280 : {
281 1 : CPLError(CE_Failure, CPLE_AssertionFailed,
282 : "Invalid color table:"
283 : "\"%s\".",
284 : osColorTableFileName.c_str());
285 :
286 1 : VSIFCloseL(oColorTable.pfDataBase);
287 1 : MM_ReleaseMainFields(&oColorTable);
288 1 : return CE_Failure;
289 : }
290 :
291 : // Checking the structure to be correct
292 20 : if (oColorTable.pField[nClauSimbol].BytesPerField == 0 ||
293 20 : oColorTable.pField[nRIndex].BytesPerField == 0 ||
294 20 : oColorTable.pField[nGIndex].BytesPerField == 0 ||
295 20 : oColorTable.pField[nBIndex].BytesPerField == 0 ||
296 20 : oColorTable.pField[nClauSimbol].FieldType != 'N' ||
297 19 : oColorTable.pField[nRIndex].FieldType != 'N' ||
298 19 : oColorTable.pField[nGIndex].FieldType != 'N' ||
299 19 : oColorTable.pField[nBIndex].FieldType != 'N')
300 : {
301 1 : CPLError(CE_Failure, CPLE_AssertionFailed,
302 : "Invalid color table:"
303 : "\"%s\".",
304 : osColorTableFileName.c_str());
305 :
306 1 : VSIFCloseL(oColorTable.pfDataBase);
307 1 : MM_ReleaseMainFields(&oColorTable);
308 1 : return CE_Failure;
309 : }
310 :
311 : // Guessing or reading the number of colors of the palette.
312 19 : MM_ACCUMULATED_BYTES_TYPE_DBF nBufferSize = oColorTable.BytesPerRecord + 1;
313 19 : char *pzsRecord = static_cast<char *>(VSI_CALLOC_VERBOSE(1, nBufferSize));
314 19 : if (!pzsRecord)
315 : {
316 0 : CPLError(CE_Failure, CPLE_OutOfMemory,
317 : "Out of memory allocating working buffer");
318 0 : VSIFCloseL(oColorTable.pfDataBase);
319 0 : MM_ReleaseMainFields(&oColorTable);
320 : }
321 19 : char *pszField = static_cast<char *>(VSI_CALLOC_VERBOSE(1, nBufferSize));
322 :
323 19 : if (!pszField)
324 : {
325 0 : CPLError(CE_Failure, CPLE_OutOfMemory,
326 : "Out of memory allocating working buffer");
327 0 : VSIFree(pzsRecord);
328 0 : VSIFCloseL(oColorTable.pfDataBase);
329 0 : MM_ReleaseMainFields(&oColorTable);
330 : }
331 :
332 19 : m_nNPaletteColors = static_cast<int>(oColorTable.nRecords); // Safe cast
333 :
334 : // Checking the size of the palette.
335 19 : if (m_nNPaletteColors < 0 || m_nNPaletteColors > 65536)
336 : {
337 0 : m_nNPaletteColors = 0;
338 0 : CPLError(CE_Failure, CPLE_AppDefined,
339 : "Invalid number of colors: %d "
340 : "in color table \"%s\".",
341 : m_nNPaletteColors, osColorTableFileName.c_str());
342 :
343 0 : VSIFree(pszField);
344 0 : VSIFree(pzsRecord);
345 0 : VSIFCloseL(oColorTable.pfDataBase);
346 0 : MM_ReleaseMainFields(&oColorTable);
347 0 : return CE_Failure;
348 : }
349 :
350 : // Getting the memory to allocate the color values
351 95 : for (int iColumn = 0; iColumn < 4; iColumn++)
352 : {
353 : try
354 : {
355 76 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
356 : }
357 0 : catch (std::bad_alloc &e)
358 : {
359 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
360 0 : VSIFree(pszField);
361 0 : VSIFree(pzsRecord);
362 0 : VSIFCloseL(oColorTable.pfDataBase);
363 0 : MM_ReleaseMainFields(&oColorTable);
364 0 : return CE_Failure;
365 : }
366 : }
367 :
368 19 : VSIFSeekL(oColorTable.pfDataBase,
369 19 : static_cast<vsi_l_offset>(oColorTable.FirstRecordOffset),
370 : SEEK_SET);
371 : /*
372 : Each record's CLAUSIMBOL field doesn't match a pixel value present in the raster,
373 : and it's used only for discovering nodata value (blanc value).
374 : The list of values is used to map every value in a color using:
375 : - Direct assignation: mode used in categorical modes but possible in continuous.
376 : - Linear scaling
377 : - Logarithmic scaling
378 : */
379 1220 : for (int nIPaletteColors = 0; nIPaletteColors < m_nNPaletteColors;
380 : nIPaletteColors++)
381 : {
382 2402 : if (oColorTable.BytesPerRecord !=
383 1201 : VSIFReadL(pzsRecord, sizeof(unsigned char),
384 1201 : oColorTable.BytesPerRecord, oColorTable.pfDataBase))
385 : {
386 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
387 : osColorTableFileName.c_str());
388 0 : VSIFree(pszField);
389 0 : VSIFree(pzsRecord);
390 0 : VSIFCloseL(oColorTable.pfDataBase);
391 0 : MM_ReleaseMainFields(&oColorTable);
392 0 : return CE_Failure;
393 : }
394 :
395 : // Nodata identification
396 1201 : memcpy(pszField,
397 1201 : pzsRecord + oColorTable.pField[nClauSimbol].AccumulatedBytes,
398 1201 : oColorTable.pField[nClauSimbol].BytesPerField);
399 1201 : pszField[oColorTable.pField[nClauSimbol].BytesPerField] = '\0';
400 2402 : CPLString osField = pszField;
401 1201 : osField.replaceAll(" ", "");
402 1201 : if (osField.empty()) // Nodata value
403 : {
404 6 : m_bHasNodata = true;
405 6 : m_nNoDataPaletteIndex = nIPaletteColors;
406 : }
407 :
408 1201 : AssignColorFromDBF(oColorTable, pzsRecord, pszField, nRIndex, nGIndex,
409 : nBIndex, nIPaletteColors);
410 : }
411 :
412 19 : VSIFree(pszField);
413 19 : VSIFree(pzsRecord);
414 19 : VSIFCloseL(oColorTable.pfDataBase);
415 19 : MM_ReleaseMainFields(&oColorTable);
416 :
417 19 : return CE_None;
418 : }
419 :
420 : // Colors in a PAL, P25 or P65 format files
421 : // Updates nNPaletteColors
422 : CPLErr
423 3 : MMRPalettes::GetPaletteColors_PAL_P25_P65(const CPLString &os_Color_Paleta_DBF)
424 :
425 : {
426 6 : CPLString osAux = CPLGetPathSafe(m_pfRel->GetRELNameChar());
427 : CPLString osColorTableFileName =
428 6 : CPLFormFilenameSafe(osAux.c_str(), os_Color_Paleta_DBF.c_str(), "");
429 :
430 : // This kind of palette has not NoData color.
431 : //bHasNodata = false;
432 :
433 6 : CPLString osExtension = CPLGetExtensionSafe(os_Color_Paleta_DBF);
434 3 : int nNReadPaletteColors = 0;
435 3 : m_nNPaletteColors = 0;
436 :
437 3 : if (osExtension.tolower() == "pal")
438 1 : m_nNPaletteColors = 64;
439 2 : else if (osExtension.tolower() == "p25")
440 1 : m_nNPaletteColors = 256;
441 1 : else if (osExtension.tolower() == "p65")
442 1 : m_nNPaletteColors = 65536;
443 : else
444 0 : return CE_None;
445 :
446 15 : for (int iColumn = 0; iColumn < 4; iColumn++)
447 : {
448 : try
449 : {
450 12 : m_aadfPaletteColors[iColumn].resize(m_nNPaletteColors, 0);
451 : }
452 0 : catch (std::bad_alloc &e)
453 : {
454 0 : CPLError(CE_Failure, CPLE_AppDefined, "%s", e.what());
455 0 : return CE_Failure;
456 : }
457 : }
458 :
459 3 : VSILFILE *fpColorTable = VSIFOpenL(osColorTableFileName, "rt");
460 3 : if (!fpColorTable)
461 : {
462 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
463 : osColorTableFileName.c_str());
464 0 : return CE_Failure;
465 : }
466 :
467 3 : nNReadPaletteColors = 0;
468 : const char *pszLine;
469 51 : while ((pszLine = CPLReadLineL(fpColorTable)) != nullptr)
470 : {
471 : // Ignore empty lines
472 48 : if (pszLine[0] == '\0')
473 0 : continue;
474 :
475 48 : const CPLStringList aosTokens(CSLTokenizeString2(pszLine, " \t", 0));
476 48 : if (aosTokens.size() != 4)
477 : {
478 0 : VSIFCloseL(fpColorTable);
479 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
480 : osColorTableFileName.c_str());
481 0 : return CE_Failure;
482 : }
483 :
484 : // Index of the color
485 : // papszTokens[0] is ignored;
486 :
487 : // RED
488 48 : m_aadfPaletteColors[0][nNReadPaletteColors] = CPLAtof(aosTokens[1]);
489 :
490 : // GREEN
491 48 : m_aadfPaletteColors[1][nNReadPaletteColors] = CPLAtof(aosTokens[2]);
492 :
493 : // BLUE
494 48 : m_aadfPaletteColors[2][nNReadPaletteColors] = CPLAtof(aosTokens[3]);
495 :
496 : // ALPHA
497 48 : m_aadfPaletteColors[3][nNReadPaletteColors] = 255.0;
498 48 : nNReadPaletteColors++;
499 : }
500 :
501 : // Filling the rest of colors.
502 3 : for (int nIColorIndex = nNReadPaletteColors;
503 65811 : nIColorIndex < m_nNPaletteColors; nIColorIndex++)
504 : {
505 65808 : m_aadfPaletteColors[0][nNReadPaletteColors] = m_sDefaultColorRGB.c1;
506 65808 : m_aadfPaletteColors[1][nNReadPaletteColors] = m_sDefaultColorRGB.c2;
507 65808 : m_aadfPaletteColors[2][nNReadPaletteColors] = m_sDefaultColorRGB.c3;
508 65808 : m_aadfPaletteColors[3][nNReadPaletteColors] = m_sDefaultColorRGB.c4;
509 65808 : nNReadPaletteColors++;
510 : }
511 :
512 3 : if (nNReadPaletteColors != m_nNPaletteColors)
513 : {
514 0 : VSIFCloseL(fpColorTable);
515 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid color table: \"%s\"",
516 : osColorTableFileName.c_str());
517 0 : return CE_Failure;
518 : }
519 :
520 3 : VSIFCloseL(fpColorTable);
521 :
522 3 : return CE_None;
523 : }
524 :
525 61 : CPLErr MMRPalettes::UpdateColorInfo()
526 : {
527 122 : CPLString os_Color_EscalatColor;
528 61 : if (m_pfRel->GetMetadataValue(SECTION_COLOR_TEXT, m_osBandSection,
529 : "Color_EscalatColor",
530 66 : os_Color_EscalatColor) &&
531 5 : !os_Color_EscalatColor.empty())
532 : {
533 5 : if (os_Color_EscalatColor.compare("AssigDirecta") == 0)
534 2 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
535 3 : else if (os_Color_EscalatColor.compare("DespOrigen") == 0)
536 0 : m_ColorScaling = ColorTreatment::ORIGIN_DISPLACEMENT;
537 3 : else if (os_Color_EscalatColor.compare("lineal") == 0)
538 3 : m_ColorScaling = ColorTreatment::LINEAR_SCALING;
539 0 : else if (os_Color_EscalatColor.compare("log_10") == 0)
540 0 : m_ColorScaling = ColorTreatment::LOG_10_SCALING;
541 0 : else if (os_Color_EscalatColor.compare("IntervalsUsuari") == 0)
542 0 : m_ColorScaling = ColorTreatment::USER_INTERVALS;
543 : }
544 : else
545 : {
546 56 : if (IsCategorical())
547 50 : m_ColorScaling = ColorTreatment::DIRECT_ASSIGNATION;
548 : else
549 6 : m_ColorScaling = ColorTreatment::LINEAR_SCALING;
550 : }
551 :
552 61 : if (m_ColorScaling == ColorTreatment::DEFAULT_SCALING)
553 0 : return CE_Failure;
554 61 : return CE_None;
555 : }
|