Range *ColorPalette::clone() const { ColorPalette *palette = new ColorPalette(); for(const auto& item : _colors){ palette->add( item->clone()); } palette->defaultColorModel(defaultColorModel()); return palette; }
QString MemoryDump::query(const int queryId, const ColorPalette& col, KnowledgeSources src) const { QString ret; Instance instance = queryInstance(queryId, src); QString s = QString("%1%2%3%4: ") .arg(col.color(ctTypeId)) .arg("0x") .arg(queryId, 0, 16) .arg(col.color(ctReset)); if (instance.isValid()) { s += QString("%1%2%3 (ID%4 0x%5%6)") .arg(col.color(ctType)) .arg(instance.typeName()) .arg(col.color(ctReset)) .arg(col.color(ctTypeId)) .arg((uint)instance.type()->id(), 0, 16) .arg(col.color(ctReset)); ret = instance.toString(&col); } else s += "(unresolved type)"; s += QString(" @%1 0x%2%3\n") .arg(col.color(ctAddress)) .arg(instance.address(), _specs.sizeofPointer << 1, 16, QChar('0')) .arg(col.color(ctReset)); ret = s + ret; return ret; }
/** * \brief Sets the drop properties */ void dropEvent(QDropEvent* event) { // Find the output location drop_index = owner->indexAt(event->pos()); if ( drop_index == -1 ) drop_index = palette.count(); // Gather up the color if ( event->mimeData()->hasColor() ) { drop_color = event->mimeData()->colorData().value<QColor>(); } else if ( event->mimeData()->hasText() ) { drop_color = QColor(event->mimeData()->text()); } drop_overwrite = false; QRectF drop_rect = indexRect(drop_index); if ( drop_index < palette.count() && drop_rect.isValid() ) { // 1 column => vertical style if ( palette.columns() == 1 || forced_columns == 1 ) { // Dragged to the last quarter of the size of the square, add after if ( event->posF().y() >= drop_rect.top() + drop_rect.height() * 3.0 / 4 ) drop_index++; // Dragged to the middle of the square, overwrite existing color else if ( event->posF().x() > drop_rect.top() + drop_rect.height() / 4 && ( event->dropAction() != Qt::MoveAction || event->source() != owner || palette.colorAt(drop_index) == emptyColor ) ) drop_overwrite = true; } else { // Dragged to the last quarter of the size of the square, add after if ( event->posF().x() >= drop_rect.left() + drop_rect.width() * 3.0 / 4 ) drop_index++; // Dragged to the middle of the square, overwrite existing color else if ( event->posF().x() > drop_rect.left() + drop_rect.width() / 4 && ( event->dropAction() != Qt::MoveAction || event->source() != owner || palette.colorAt(drop_index) == emptyColor ) ) drop_overwrite = true; } } owner->update(); }
bool RasterCoverageConnector::handlePaletteCase(Size<> &rastersize, RasterCoverage* raster) { auto layerHandle = gdal()->getRasterBand(_handle->handle(), 1); auto paletteHandle = gdal()->getColorPalette(layerHandle); ColorPalette *palette = new ColorPalette(); if (!paletteHandle) return false; int count = gdal()->getColorPaletteSize(paletteHandle); if ( count == 0) return false; ColorRangeBase::ColorModel model; GDALPaletteInterp colorType = gdal()->getPaletteColorInterpretation(paletteHandle); for(int i = 0; i < count; ++i) { GDALColorEntry *entry = gdal()->getColorPaletteEntry(paletteHandle, i); if ( !entry) continue; QColor clr; switch ( colorType){ case GPI_RGB: clr.setRgb(entry->c1, entry->c2, entry->c3); model = ColorRangeBase::cmRGBA; break; case GPI_HLS: clr.setHsl(entry->c1, entry->c2, entry->c3); break; model = ColorRangeBase::cmHSLA; break; case GPI_CMYK: clr.setCmyk(entry->c1, entry->c2, entry->c3, entry->c4); model = ColorRangeBase::cmCYMKA; break; case GPI_Gray: clr.setRgb(entry->c1, entry->c1, entry->c1); model = ColorRangeBase::cmGREYSCALE; } clr.setAlpha(entry->c4); palette->add(new ColorItem(clr)); } palette->defaultColorModel(model); _typeSize = 1; _gdalValueType = gdal()->rasterDataType(layerHandle); raster->datadefRef() = DataDefinition(IDomain("colorpalette"), reinterpret_cast<Range *>(palette)); return true; }
DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const *colorFormatDescriptor, char const *nameCStr, uint8_t const *colorData, int colorCount) { DENG2_ASSERT(nameCStr != 0 && colorFormatDescriptor != 0 && colorData != 0); LOG_AS("R_CreateColorPalette"); try { using namespace res; String name(nameCStr); if(name.isEmpty()) { LOG_RES_WARNING("Invalid/zero-length name specified, ignoring."); return 0; } QVector<Vector3ub> colors = ColorTableReader::read(colorFormatDescriptor, colorCount, colorData); auto &palettes = Resources::get().colorPalettes(); // Replacing an existing palette? if(palettes.hasColorPalette(name)) { ColorPalette &palette = palettes.colorPalette(name); palette.replaceColorTable(colors); return palette.id(); } // A new palette. ColorPalette *palette = new ColorPalette(colors); palettes.addColorPalette(*palette, name); return palette->id(); } catch(res::ColorTableReader::FormatError const &er) { LOG_RES_WARNING("Error creating/replacing color palette '%s':\n") << nameCStr << er.asText(); } return 0; }
bool save(ColorPalette& palette, const QString& suggested_filename = QString()) { // Attempt to save with the existing file names if ( !suggested_filename.isEmpty() && attemptSave(palette, suggested_filename) ) return true; if ( attemptSave(palette, palette.fileName()) ) return true; // Set up the save directory QDir save_dir(save_path); if ( !save_dir.exists() && !QDir().mkdir(save_path) ) return false; // Attempt to save as (Name).gpl QString filename = palette.name()+".gpl"; if ( !save_dir.exists(filename) && attemptSave(palette, save_dir.absoluteFilePath(filename)) ) return true; // Get all of the files matching the pattern *.gpl save_dir.setNameFilters(QStringList() << "*.gpl"); save_dir.setFilter(QDir::Files); QStringList existing_files = save_dir.entryList(); // For all the files that match (Name)(Number).gpl, find the maximum (Number) QRegularExpression name_regex(QRegularExpression::escape(palette.name())+"([0-9]+)\\.gpl"); int max = 0; for ( const auto& existing_file : existing_files ) { QRegularExpressionMatch match = name_regex.match(existing_file); if ( match.hasMatch() ) { int num = match.captured(1).toInt(); if ( num > max ) max = num; } } return attemptSave(palette, save_dir.absoluteFilePath(QString("%1%2.gpl").arg(palette.name()).arg(max+1)) ); }
/** * \brief Number of rows/columns in the palette */ QSize rowcols() { int count = palette.count(); if ( count == 0 ) return QSize(); if ( forced_rows ) return QSize(std::ceil( float(count) / forced_rows ), forced_rows); int columns = palette.columns(); if ( forced_columns ) columns = forced_columns; else if ( columns == 0 ) columns = qMin(palette.count(), owner->width() / color_size.width()); int rows = std::ceil( float(count) / columns ); return QSize(columns, rows); }
void ColorPalettes::addColorPalette(ColorPalette &newPalette, String const &name) { // Do we already own this palette? if (d->colorPalettes.contains(newPalette.id())) return; d->colorPalettes.insert(newPalette.id(), &newPalette); if (!name.isEmpty()) { d->colorPaletteNames.insert(name, &newPalette); } // If this is the first palette automatically set it as the default. if (d->colorPalettes.count() == 1) { d->defaultColorPalette = newPalette.id(); } DENG2_FOR_AUDIENCE2(Addition, i) i->colorPaletteAdded(newPalette); }
void ColorPaletteModel::load() { beginResetModel(); p->palettes.clear(); QStringList filters; filters << "*.gpl"; for ( const QString& directory_name : p->search_paths ) { QDir directory(directory_name); directory.setNameFilters(filters); directory.setFilter(QDir::Files|QDir::Readable); directory.setSorting(QDir::Name); for ( const QFileInfo& file : directory.entryInfoList() ) { ColorPalette palette; if ( palette.load(file.absoluteFilePath()) ) { p->palettes.push_back(palette); } } } endResetModel(); }
bool CreatePaletteDomain::execute(ExecutionContext *ctx, SymbolTable &symTable) { if (_prepState == sNOTPREPARED) if((_prepState = prepare(ctx, symTable)) != sPREPARED) return false; IColorDomain colordomain; colordomain.prepare(); colordomain->setDescription(_domaindesc); if ( _parentdomain.isValid()) colordomain->setParent(_parentdomain); ColorPalette *palette = new ColorPalette(); for(int i=0; i < _items.size(); ++i){ palette->add(new ColorItem(_items[i])); } colordomain->range(palette); QVariant value; value.setValue<IDomain>(colordomain); ctx->setOutput(symTable,value,colordomain->name(),itDOMAIN,colordomain->source()); return true; }
ColorPalette ColorPalette::fromColorTable(const QVector<QRgb>& table) { ColorPalette palette; palette.loadColorTable(table); return palette; }
ColorPalette ColorPalette::fromFile(const QString& name) { ColorPalette p; p.load(name); return p; }
ColorPalette ColorPalette::fromImage(const QImage& image) { ColorPalette p; p.fromImage(image); return p; }
QString MemoryDump::dump(const QString& type, quint64 address, int length, const ColorPalette& col) const { if (type == "char") { char c; if (_vmem->readAtomic(address, &c, sizeof(char)) != sizeof(char)) queryError(QString("Cannot read memory from address 0x%1") .arg(address, (_specs.sizeofPointer << 1), 16, QChar('0'))); return QString("%1 (0x%2)").arg(c).arg(c, (sizeof(c) << 1), 16, QChar('0')); } if (type == "int") { qint32 i; if (_vmem->readAtomic(address, (char*)&i, sizeof(qint32)) != sizeof(qint32)) queryError(QString("Cannot read memory from address 0x%1") .arg(address, (_specs.sizeofPointer << 1), 16, QChar('0'))); return QString("%1 (0x%2)").arg(i).arg((quint32)i, (sizeof(i) << 1), 16, QChar('0')); } if (type == "long") { qint64 l; if (_vmem->readAtomic(address, (char*)&l, sizeof(qint64)) != sizeof(qint64)) queryError(QString("Cannot read memory from address 0x%1") .arg(address, (_specs.sizeofPointer << 1), 16, QChar('0'))); return QString("%1 (0x%2)").arg(l).arg((quint64)l, (sizeof(l) << 1), 16, QChar('0')); } if (type == "raw" || type == "hex") { QString ret; const int buflen = 256, linelen = 16; char buf[buflen]; char bufstr[linelen + 1] = {0}; // Make sure we got a valid length if (length < 0) queryError(QString("No valid length given for dumping raw memory")); int totalBytesRead = 0, col = 0; while (length > 0) { int bytesRead = _vmem->readAtomic(address, buf, qMin(buflen, length)); length -= bytesRead; int i = 0; while (i < bytesRead) { // New line every 16 bytes begins with address if (totalBytesRead % 16 == 0) { if (totalBytesRead > 0) { ret += QString(" |%0|\n").arg(bufstr, -linelen); memset(bufstr, 0, linelen + 1); col = 0; } ret += QString("%1 ").arg(address, _specs.sizeofPointer << 1, 16, QChar('0')); } // Wider column after 8 bytes if (totalBytesRead % 8 == 0) ret += ' '; // Write the character as hex string if ((unsigned char)buf[i] < 16) ret += '0'; ret += QString::number((unsigned char)buf[i], 16) + ' '; // Add character to string buffer, if it's an ASCII char if ( ((unsigned char)buf[i] >= 32) && ((unsigned char)buf[i] < 127) ) bufstr[col] = buf[i]; else bufstr[col] = '.'; ++col; ++totalBytesRead; ++address; ++i; } } // Finish it up if (col > 0) { while (col < linelen) { ret += " "; if (col % 8 == 0) ret += ' '; ++col; } ret += QString(" |%0|").arg(bufstr, -linelen); } return ret; } QStringList components = type.split('.', QString::SkipEmptyParts); Instance result; if (!components.isEmpty()) { // Get first instance result = getInstanceAt(components.first(), address, QStringList("user")); components.pop_front(); while (!components.isEmpty()) { result = getNextInstance(components.first(), result, ksNone); components.pop_front(); } return QString("%1%2%3 (ID%4 0x%5%6) @%7 0x%8%9\n") .arg(col.color(ctType)) .arg(result.typeName()) .arg(col.color(ctReset)) .arg(col.color(ctTypeId)) .arg((uint)result.type()->id(), 0, 16) .arg(col.color(ctReset)) .arg(col.color(ctAddress)) .arg(result.address(), 0, 16) .arg(col.color(ctReset)) + result.toString(&col); } queryError3("Unknown type: " + type, QueryException::ecUnresolvedType, type); return QString(); }
QString MemoryDump::query(const QString& queryString, const ColorPalette& col, KnowledgeSources src) const { QString ret; if (queryString.isEmpty()) { // Generate a list of all global variables for (int i = 0; i < _factory->vars().size(); i++) { if (i > 0) ret += "\n"; Variable* var = _factory->vars().at(i); ret += var->prettyName(); } } else { Instance instance = queryInstance(queryString, src); QString s = QString("%1%2%3: ") .arg(col.color(ctBold)) .arg(queryString) .arg(col.color(ctReset)); if (instance.isValid()) { s += QString("%1%2%3 (ID%4 0x%5%6)") .arg(col.color(ctType)) .arg(instance.typeName()) .arg(col.color(ctReset)) .arg(col.color(ctTypeId)) .arg((uint)instance.type()->id(), 0, 16) .arg(col.color(ctReset)); if (instance.isNull()) ret = QString(col.color(ctAddress)) + "NULL" + QString(col.color(ctReset)); else { ret = instance.toString(&col); } } else s += "(unresolved type)"; s += QString(" @%1 0x%2%3") .arg(col.color(ctAddress)) .arg(instance.address(), _specs.sizeofPointer << 1, 16, QChar('0')) .arg(col.color(ctReset)); if (instance.bitSize() >= 0) { s += QString("[%1%3%2:%1%4%2]") .arg(col.color(ctOffset)) .arg(col.color(ctReset)) .arg((instance.size() << 3) - instance.bitOffset() - 1) .arg((instance.size() << 3) - instance.bitOffset() - instance.bitSize()); } ret = s + "\n" + ret; } return ret; }
bool attemptSave(ColorPalette& palette, const QString& filename) { if ( filename.isEmpty() ) return false; return palette.save(filename); }
void GL_CalcLuminance(duint8 const *buffer, dint width, dint height, dint pixelSize, colorpaletteid_t paletteId, dfloat *retBrightX, dfloat *retBrightY, ColorRawf *retColor, dfloat *retLumSize) { DENG2_ASSERT(buffer && retBrightX && retBrightY && retColor && retLumSize); static duint8 const sizeLimit = 192, brightLimit = 224, colLimit = 192; ColorPalette *palette = (pixelSize == 1? &resSys().colorPalette(paletteId) : nullptr); // Apply the defaults. // Default to the center of the texture. *retBrightX = *retBrightY = .5f; // Default to black (i.e., no light). for(dint c = 0; c < 3; ++c) { retColor->rgb[c] = 0; } retColor->alpha = 1; // Default to a zero-size light. *retLumSize = 0; dint region[4]; FindClipRegionNonAlpha(buffer, width, height, pixelSize, region); dd_bool zeroAreaRegion = (region[0] > region[1] || region[2] > region[3]); if(zeroAreaRegion) return; // // Image contains at least one non-transparent pixel. // long bright[2]; for(dint i = 0; i < 2; ++i) { bright[i] = 0; } long average[3], lowAvg[3]; for(dint i = 0; i < 3; ++i) { average[i] = 0; lowAvg[i] = 0; } duint8 const *src = buffer; // In paletted mode, the alpha channel follows the actual image. duint8 const *alphaSrc = &buffer[width * height]; // Skip to the start of the first column. if(region[2] > 0) { src += pixelSize * width * region[2]; alphaSrc += width * region[2]; } duint8 rgb[3]; dint avgCnt = 0, lowCnt = 0; dint cnt = 0, posCnt = 0; for(dint y = region[2]; y <= region[3]; ++y) { // Skip to the beginning of the row. if(region[0] > 0) { src += pixelSize * region[0]; alphaSrc += region[0]; } for(dint x = region[0]; x <= region[1]; ++x, src += pixelSize, alphaSrc++) { // Alpha pixels don't count. Why? -ds dd_bool const pixelIsTransparent = (pixelSize == 1? *alphaSrc < 255 : pixelSize == 4? src[3] < 255 : false); if(pixelIsTransparent) continue; if(pixelSize == 1) { Vector3ub palColor = palette->color(*src); rgb[0] = palColor.x; rgb[1] = palColor.y; rgb[2] = palColor.z; } else if(pixelSize >= 3) { std::memcpy(rgb, src, 3); } // Bright enough? if(rgb[0] > brightLimit || rgb[1] > brightLimit || rgb[2] > brightLimit) { // This pixel will participate in calculating the average center point. posCnt++; bright[0] += x; bright[1] += y; } // Bright enough to affect size? if(rgb[0] > sizeLimit || rgb[1] > sizeLimit || rgb[2] > sizeLimit) cnt++; // How about the color of the light? if(rgb[0] > colLimit || rgb[1] > colLimit || rgb[2] > colLimit) { avgCnt++; for(dint c = 0; c < 3; ++c) { average[c] += rgb[c]; } } else { lowCnt++; for(dint c = 0; c < 3; ++c) { lowAvg[c] += rgb[c]; } } } // Skip to the end of this row. if(region[1] < width - 1) { src += pixelSize * (width - 1 - region[1]); alphaSrc += (width - 1 - region[1]); } } if(posCnt) { // Calculate the average of the bright pixels. *retBrightX = (long double) bright[0] / posCnt; *retBrightY = (long double) bright[1] / posCnt; } else { // No bright pixels - Place the origin at the center of the non-alpha region. *retBrightX = region[0] + (region[1] - region[0]) / 2.0f; *retBrightY = region[2] + (region[3] - region[2]) / 2.0f; } // Determine rounding (to the nearest pixel center). dint roundXDir = dint( *retBrightX + .5f ) == dint( *retBrightX )? 1 : -1; dint roundYDir = dint( *retBrightY + .5f ) == dint( *retBrightY )? 1 : -1; // Apply all rounding and output as decimal. *retBrightX = (ROUND(*retBrightX) + .5f * roundXDir) / dfloat( width ); *retBrightY = (ROUND(*retBrightY) + .5f * roundYDir) / dfloat( height ); if(avgCnt || lowCnt) { // The color. if(!avgCnt) { // Low-intensity color average. for(dint c = 0; c < 3; ++c) { retColor->rgb[c] = lowAvg[c] / lowCnt / 255.f; } } else { // High-intensity color average. for(dint c = 0; c < 3; ++c) { retColor->rgb[c] = average[c] / avgCnt / 255.f; } } Vector3f color(retColor->rgb); R_AmplifyColor(color); for(dint i = 0; i < 3; ++i) { retColor->rgb[i] = color[i]; } // How about the size of the light source? /// @todo These factors should be cvars. *retLumSize = MIN_OF(((2 * cnt + avgCnt) / 3.0f / 70.0f), 1); } /* DEBUG_Message(("GL_CalcLuminance: width %dpx, height %dpx, bits %d\n" " cell region X[%d, %d] Y[%d, %d]\n" " flare X= %g Y=%g %s\n" " flare RGB[%g, %g, %g] %s\n", width, height, pixelSize, region[0], region[1], region[2], region[3], *retBrightX, *retBrightY, (posCnt? "(average)" : "(center)"), retColor->red, retColor->green, retColor->blue, (avgCnt? "(hi-intensity avg)" : lowCnt? "(low-intensity avg)" : "(white light)"))); */ }
void fixUnnamed(ColorPalette& palette) { if ( palette.name().isEmpty() ) palette.setName(ColorPaletteModel::tr("Unnamed")); }
bool test_ColorPalette() { cout << "Testing AnsiGL::ColorPalette..." << endl; // New create a color palette ColorPalette Palette; ANNOUNCE( "AnsiGL::ColorPalette", "Add( ColorDef::Ptr )" ); ColorDef::Ptr NewColor = ColorDef::Ptr( new ColorDef(ANSISysColor_Red, ANSISysColor_Black) ); Palette.Add( NewColor ); NewColor = ColorDef::Ptr( new ColorDef(ANSISysColor_Yellow, ANSISysColor_Cyan) ); Palette.Add( NewColor ); NewColor = ColorDef::Ptr( new ColorDef(ANSISysColor_Red, ANSISysColor_Black) ); Palette.Add( NewColor ); NewColor = ColorDef::Ptr( new ColorDef(ANSISysColor_BoldBlue, ANSISysColor_White) ); Palette.Add( NewColor ); NewColor = ColorDef::Ptr( new ColorDef(ANSISysColor_Yellow, ANSISysColor_Cyan) ); Palette.Add( NewColor ); NewColor = ColorDef::Ptr( new ColorDef(ANSISysColor_Red, ANSISysColor_Black) ); Palette.Add( NewColor ); TEST( Palette.size() == 3 ); if ( gVerbose ) { for ( unsigned int i = 0; i < Palette.size(); ++i ) cout << "Palette Index " << i << ": " << "\033[0;" << Palette[i]->Render() << "m" << "Test" << "\033[0m" << endl; } ColorDef TestColor( ANSISysColor_Yellow, ANSISysColor_Cyan ); ColorDef::Ptr CurColor; ANNOUNCE( "", "operator[]( const int index ) const" ); CurColor = Palette[1]; bool opIndex_Result1 = (*CurColor) == TestColor; CurColor = Palette[0]; TestColor.FG.Set( ANSISysColor_Red ); TestColor.BG.Set( ANSISysColor_Black ); TEST( opIndex_Result1 && (*CurColor) == TestColor ); ANNOUNCE( "", "FindIndex( ColorDef color )" ); bool FindIndex_Result1 = (Palette.FindIndex( TestColor ) == 0); TestColor.FG.Set( ANSISysColor_Yellow ); TestColor.BG.Set( ANSISysColor_Cyan ); bool FindIndex_Result2 = (Palette.FindIndex( TestColor ) == 1); TEST( FindIndex_Result1 && FindIndex_Result2 ); ANNOUNCE( "", "InvertColors()" ); Palette.InvertColors(); TestColor.FG.Set( ANSISysColor_Cyan ); TestColor.BG.Set( ANSISysColor_Yellow ); TEST( Palette.FindIndex( TestColor ) ); ANNOUNCE( "", "Remove( ColorDef color )" ); Palette.Remove( TestColor ); TestColor.FG.Set( ANSISysColor_Black ); TestColor.BG.Set( ANSISysColor_Red ); TEST( Palette.size() == 2 && Palette.FindIndex( TestColor ) == 0 ); ANNOUNCE( "", "Remove( int index )" ); Palette.Remove( 0 ); TEST( Palette.size() == 1 ); cout << "All tests for ColorPalette completed successfully!" << endl; return true; }