void ChangeResolutionAction::DecreaseTime(TimeFrequencyData &timeFrequencyData) { if(_useMaskInAveraging) { DecreaseTimeWithMask(timeFrequencyData); } else { size_t imageCount = timeFrequencyData.ImageCount(); for(size_t i=0;i<imageCount;++i) { Image2DCPtr image = timeFrequencyData.GetImage(i); Image2DPtr newImage(new Image2D(image->ShrinkHorizontally(_timeDecreaseFactor))); timeFrequencyData.SetImage(i, std::move(newImage)); } size_t maskCount = timeFrequencyData.MaskCount(); for(size_t i=0;i<maskCount;++i) { Mask2DCPtr mask = timeFrequencyData.GetMask(i); Mask2DPtr newMask(new Mask2D(mask->ShrinkHorizontally(_timeDecreaseFactor))); timeFrequencyData.SetMask(i, std::move(newMask)); } } }
void ImageWidget::update(Cairo::RefPtr<Cairo::Context> cairo, unsigned width, unsigned height) { Image2DCPtr image = _image; Mask2DCPtr mask = GetActiveMask(), originalMask = _originalMask, alternativeMask = _alternativeMask; unsigned int startX = (unsigned int) round(_startHorizontal * image->Width()), startY = (unsigned int) round(_startVertical * image->Height()), endX = (unsigned int) round(_endHorizontal * image->Width()), endY = (unsigned int) round(_endVertical * image->Height()); size_t imageWidth = endX - startX, imageHeight = endY - startY; if(imageWidth > 30000) { int shrinkFactor = (imageWidth + 29999) / 30000; image = image->ShrinkHorizontally(shrinkFactor); mask = mask->ShrinkHorizontally(shrinkFactor); if(originalMask != 0) originalMask = originalMask->ShrinkHorizontally(shrinkFactor); if(alternativeMask != 0) alternativeMask = alternativeMask->ShrinkHorizontally(shrinkFactor); startX /= shrinkFactor; endX /= shrinkFactor; imageWidth = endX - startX; } num_t min, max; findMinMax(image, mask, min, max); // If these are not yet created, they are 0, so ok to delete. delete _horiScale; delete _vertScale; delete _colorScale; delete _plotTitle; if(_showXYAxes) { _vertScale = new VerticalPlotScale(); _vertScale->SetDrawWithDescription(_showYAxisDescription); _horiScale = new HorizontalPlotScale(); _horiScale->SetDrawWithDescription(_showXAxisDescription); } else { _vertScale = 0; _horiScale = 0; } if(_showColorScale) { _colorScale = new ColorScale(); _colorScale->SetDrawWithDescription(_showZAxisDescription); } else { _colorScale = 0; } if(_showXYAxes) { if(_metaData != 0 && _metaData->HasBand()) { _vertScale->InitializeNumericTicks(_metaData->Band().channels[startY].frequencyHz / 1e6, _metaData->Band().channels[endY-1].frequencyHz / 1e6); _vertScale->SetUnitsCaption("Frequency (MHz)"); } else { _vertScale->InitializeNumericTicks(-0.5 + startY, 0.5 + endY - 1.0); } if(_metaData != 0 && _metaData->HasObservationTimes()) { _horiScale->InitializeTimeTicks(_metaData->ObservationTimes()[startX], _metaData->ObservationTimes()[endX-1]); _horiScale->SetUnitsCaption("Time"); } else { _horiScale->InitializeNumericTicks(-0.5 + startX, 0.5 + endX - 1.0); } if(_manualXAxisDescription) _horiScale->SetUnitsCaption(_xAxisDescription); if(_manualYAxisDescription) _vertScale->SetUnitsCaption(_yAxisDescription); } if(_metaData != 0) { if(_showColorScale && _metaData->ValueDescription()!="") { if(_metaData->ValueUnits()!="") _colorScale->SetUnitsCaption(_metaData->ValueDescription() + " (" + _metaData->ValueUnits() + ")"); else _colorScale->SetUnitsCaption(_metaData->ValueDescription()); } } if(_showColorScale) { if(_scaleOption == LogScale) _colorScale->InitializeLogarithmicTicks(min, max); else _colorScale->InitializeNumericTicks(min, max); if(_manualZAxisDescription) _colorScale->SetUnitsCaption(_zAxisDescription); } if(_showTitle && !actualTitleText().empty()) { _plotTitle = new Title(); _plotTitle->SetText(actualTitleText()); _plotTitle->SetPlotDimensions(width, height, 0.0); _topBorderSize = _plotTitle->GetHeight(cairo); } else { _plotTitle = 0; _topBorderSize = 10.0; } // The scale dimensions are depending on each other. However, since the height of the horizontal scale is practically // not dependent on other dimensions, we give the horizontal scale temporary width/height, so that we can calculate its height: if(_showXYAxes) { _horiScale->SetPlotDimensions(width, height, 0.0, 0.0); _bottomBorderSize = _horiScale->GetHeight(cairo); _rightBorderSize = _horiScale->GetRightMargin(cairo); _vertScale->SetPlotDimensions(width - _rightBorderSize + 5.0, height - _topBorderSize - _bottomBorderSize, _topBorderSize); _leftBorderSize = _vertScale->GetWidth(cairo); } else { _bottomBorderSize = 0.0; _rightBorderSize = 0.0; _leftBorderSize = 0.0; } if(_showColorScale) { _colorScale->SetPlotDimensions(width - _rightBorderSize, height - _topBorderSize, _topBorderSize); _rightBorderSize += _colorScale->GetWidth(cairo) + 5.0; } if(_showXYAxes) { _horiScale->SetPlotDimensions(width - _rightBorderSize + 5.0, height -_topBorderSize - _bottomBorderSize, _topBorderSize, _vertScale->GetWidth(cairo)); } class ColorMap *colorMap = createColorMap(); const double minLog10 = min>0.0 ? log10(min) : 0.0, maxLog10 = max>0.0 ? log10(max) : 0.0; if(_showColorScale) { for(unsigned x=0;x<256;++x) { num_t colorVal = (2.0 / 256.0) * x - 1.0; num_t imageVal; if(_scaleOption == LogScale) imageVal = exp10((x / 256.0) * (log10(max) - minLog10) + minLog10); else imageVal = (max-min) * x / 256.0 + min; double r = colorMap->ValueToColorR(colorVal), g = colorMap->ValueToColorG(colorVal), b = colorMap->ValueToColorB(colorVal); _colorScale->SetColorValue(imageVal, r/255.0, g/255.0, b/255.0); } } _imageSurface.clear(); _imageSurface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, imageWidth, imageHeight); _imageSurface->flush(); unsigned char *data = _imageSurface->get_data(); size_t rowStride = _imageSurface->get_stride(); Mask2DPtr highlightMask; if(_highlighting) { highlightMask = Mask2D::CreateSetMaskPtr<false>(image->Width(), image->Height()); _highlightConfig->Execute(image, highlightMask, true, 10.0); } const bool originalActive = _showOriginalMask && originalMask != 0, altActive = _showAlternativeMask && alternativeMask != 0; for(unsigned long y=startY;y<endY;++y) { guint8* rowpointer = data + rowStride * (endY - y - 1); for(unsigned long x=startX;x<endX;++x) { int xa = (x-startX) * 4; unsigned char r,g,b,a; if(_highlighting && highlightMask->Value(x, y) != 0) { r = 255; g = 0; b = 0; a = 255; } else if(originalActive && originalMask->Value(x, y)) { r = 255; g = 0; b = 255; a = 255; } else if(altActive && alternativeMask->Value(x, y)) { r = 255; g = 255; b = 0; a = 255; } else { num_t val = image->Value(x, y); if(val > max) val = max; else if(val < min) val = min; if(_scaleOption == LogScale) { if(image->Value(x, y) <= 0.0) val = -1.0; else val = (log10(image->Value(x, y)) - minLog10) * 2.0 / (maxLog10 - minLog10) - 1.0; } else val = (image->Value(x, y) - min) * 2.0 / (max - min) - 1.0; if(val < -1.0) val = -1.0; else if(val > 1.0) val = 1.0; r = colorMap->ValueToColorR(val); g = colorMap->ValueToColorG(val); b = colorMap->ValueToColorB(val); a = colorMap->ValueToColorA(val); } rowpointer[xa]=b; rowpointer[xa+1]=g; rowpointer[xa+2]=r; rowpointer[xa+3]=a; } } delete colorMap; if(_segmentedImage != 0) { for(unsigned long y=startY;y<endY;++y) { guint8* rowpointer = data + rowStride * (y - startY); for(unsigned long x=startX;x<endX;++x) { if(_segmentedImage->Value(x,y) != 0) { int xa = (x-startX) * 4; rowpointer[xa]=IntMap::R(_segmentedImage->Value(x,y)); rowpointer[xa+1]=IntMap::G(_segmentedImage->Value(x,y)); rowpointer[xa+2]=IntMap::B(_segmentedImage->Value(x,y)); rowpointer[xa+3]=IntMap::A(_segmentedImage->Value(x,y)); } } } } _imageSurface->mark_dirty(); while(_imageSurface->get_width() > (int) width || _imageSurface->get_height() > (int) height) { unsigned newWidth = _imageSurface->get_width(), newHeight = _imageSurface->get_height(); if(newWidth > width) newWidth = width; if(newHeight > height) newHeight = height; downsampleImageBuffer(newWidth, newHeight); } _isInitialized = true; _initializedWidth = width; _initializedHeight = height; redrawWithoutChanges(cairo, width, height); }