void Chunk::Write(BYTE* buffer) { DWORD padsize = GetPaddedSize(size) - size; memcpy(buffer, id, 4); *(DWORD*)(buffer+4) = size + padsize; // Microsoft says the chunkSize doesn't contain padding size, but many software cannot handle the alignment. memcpy(buffer+8, data, GetPaddedSize(size)); }
UINT ListTypeChunk::GetSize() { UINT size = 12; //id + size + "LIST" //for(Chunk ck : childChunks) //C++0X syntax, not supported in MSVC (f**k Microsoft) //for_each (ck, childChunks) for (auto iter = this->childChunks.begin(); iter != childChunks.end(); iter++) size += (*iter)->GetSize(); return GetPaddedSize(size); }
void Chunk::SetData(const void* src, DWORD datasize) { size = datasize; // set the size and copy from the data source datasize = GetPaddedSize(size); if (data != NULL) { delete[] data; data = NULL; } data = new BYTE[datasize]; memcpy(data, src, size); // Add pad byte DWORD padsize = datasize - size; if (padsize != 0) { memset(data + size, 0, padsize); } }
void ListTypeChunk::Write(BYTE* buffer) { memcpy(buffer, this->id, 4); memcpy(buffer+8, this->type, 4); UINT bufOffset = 12; //for(Chunk ck : childChunks) //C++0X syntax, not supported in MSVC (f**k Microsoft) //for_each (ck, childChunks) for (auto iter = this->childChunks.begin(); iter != childChunks.end(); iter++) { (*iter)->Write(buffer+bufOffset); bufOffset += (*iter)->GetSize(); } DWORD size = bufOffset; DWORD padsize = GetPaddedSize(size) - size; *(DWORD*)(buffer+4) = size + padsize - 8; // Microsoft says the chunkSize doesn't contain padding size, but many software cannot handle the alignment. // Add pad byte if (padsize != 0) { memset(data + size, 0, padsize); } }
void HistogramDrawingArea::DrawRowColGridLabels( Cairo::RefPtr<Cairo::Context> refCairo, unsigned int numPixelValues, unsigned int numValues ) { // Reserve the outside 10% float paddedLeft, paddedTop, paddedWidth, paddedHeight; GetPaddedSize( paddedLeft, paddedTop, paddedWidth, paddedHeight ); refCairo->save(); // Set draw color refCairo->set_source_rgb(0, 0, 0); // Set the font parameters refCairo->select_font_face( "monospace", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD ); refCairo->set_font_size( 10 ); const int k_numPartitions = 8; for ( int i=0; i <= k_numPartitions; i++ ) { const float fraction = i / static_cast<float>(k_numPartitions); char caption[32]; float dimensionValue = numValues * fraction; sprintf( caption, "%.0f", dimensionValue ); const float xOffset = paddedLeft + (paddedWidth * fraction); const float yOffset = paddedTop + paddedHeight + (paddedTop/2); Cairo::TextExtents textExtents; refCairo->get_text_extents( caption, textExtents ); refCairo->move_to( xOffset - (textExtents.width / 2), yOffset + (textExtents.height / 2) ); refCairo->show_text( caption ); } for ( int i=1; i <= k_numPartitions; i++ ) { const float fraction = i / static_cast<float>(k_numPartitions); char caption[32]; float pixelValue = numPixelValues * fraction; sprintf( caption, "%.0f", pixelValue ); float yOffset = paddedTop + paddedHeight - (paddedHeight * fraction); Cairo::TextExtents textExtents; refCairo->get_text_extents( caption, textExtents ); refCairo->move_to( (paddedLeft/2) - (textExtents.width / 2), yOffset + (textExtents.height / 2) ); refCairo->show_text( caption ); } refCairo->restore(); }
void HistogramDrawingArea::DrawSingleRowColLine( Cairo::RefPtr<Cairo::Context> refCairo, std::vector<unsigned int> vecData, unsigned int numValues, double red, double green, double blue ) { refCairo->save(); // Reserve the outside 10% float paddedLeft, paddedTop, paddedWidth, paddedHeight; GetPaddedSize( paddedLeft, paddedTop, paddedWidth, paddedHeight ); const float xScale = paddedWidth / static_cast<float>(vecData.size()); const float yScale = paddedHeight / static_cast<float>(numValues); // Set draw color refCairo->set_source_rgb(red, green, blue); // Set line width refCairo->set_line_width(1.0); int k_pixelsToAvg = static_cast<int>( vecData.size() / paddedWidth); if ( k_pixelsToAvg == 0 ) { k_pixelsToAvg = 1; } const unsigned int dataSize = static_cast<unsigned int>(vecData.size()); for ( unsigned int i=0; i < dataSize; i++ ) { unsigned int maxVal = 0; for ( int j=0; j < k_pixelsToAvg; j++ ) { if ( i+j >= dataSize ) { break; } if ( vecData[i+j] > maxVal ) { maxVal = vecData[i+j]; } } // Calculate the scaled height of the current percentage float yScaledHeight = yScale * maxVal; if ( i == 0 ) { refCairo->move_to( paddedLeft, (paddedTop + paddedHeight - yScaledHeight) ); } refCairo->line_to( paddedLeft + (xScale * i), paddedTop + paddedHeight - yScaledHeight ); } refCairo->stroke(); refCairo->restore(); }
void HistogramDrawingArea::DrawHistogramGridLabels( Cairo::RefPtr<Cairo::Context> refCairo ) { // Reserve the outside 10% float paddedLeft, paddedTop, paddedWidth, paddedHeight; GetPaddedSize( paddedLeft, paddedTop, paddedWidth, paddedHeight ); refCairo->save(); // Set draw color refCairo->set_source_rgb(0, 0, 0); // Set the font parameters refCairo->select_font_face( "monospace", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD ); refCairo->set_font_size( 10 ); const int k_numPartitions = 8; // Render the x-axis labels for ( int i=0; i <= k_numPartitions; i++ ) { const float fraction = i / static_cast<float>(k_numPartitions); unsigned int maxNumPixelValues = 0; for ( int j=0; j < ImageStatistics::NUM_STATISTICS_CHANNELS; j++ ) { unsigned int numPixelValues = 0; m_histogramStats.GetNumPixelValues( static_cast<ImageStatistics::StatisticsChannel>(j), &numPixelValues ); maxNumPixelValues = std::max( numPixelValues, maxNumPixelValues ); } char caption[32]; float pixelValue; if ( maxNumPixelValues == 0 ) { pixelValue = 256 * fraction; } else { pixelValue = maxNumPixelValues * fraction; } sprintf( caption, "%.0f", pixelValue ); const float xOffset = paddedLeft + (paddedWidth * fraction); const float yOffset = paddedTop + paddedHeight + (paddedTop/2); //height - paddedTop; Cairo::TextExtents textExtents; refCairo->get_text_extents( caption, textExtents ); refCairo->move_to( xOffset - (textExtents.width / 2), yOffset + (textExtents.height / 2) ); refCairo->show_text( caption ); } // Render the y-axis labels for ( int i=1; i < k_numPartitions; i++ ) { if ( i % 2 != 0 ) { continue; } const float fraction = i / static_cast<float>(k_numPartitions); float scaleRatio = 100 / static_cast<float>(m_maxVal); float yOffset = paddedTop + paddedHeight - (paddedHeight * fraction * scaleRatio); char caption[32]; sprintf( caption, "%u%%", (i*100)/k_numPartitions ); if ( yOffset > paddedTop ) { Cairo::TextExtents textExtents; refCairo->get_text_extents( caption, textExtents ); refCairo->move_to( (paddedLeft / 2) - (textExtents.width / 2), yOffset + (textExtents.height / 2) ); refCairo->show_text( caption ); } } refCairo->restore(); }
void HistogramDrawingArea::DrawBackgroundGrid( Cairo::RefPtr<Cairo::Context> refCairo ) { // Reserve the outside 10% float paddedLeft, paddedTop, paddedWidth, paddedHeight; GetPaddedSize( paddedLeft, paddedTop, paddedWidth, paddedHeight ); refCairo->save(); // Set draw color refCairo->set_source_rgb(0, 0, 0); // Set line width refCairo->set_line_width(1.0); // Draw a horizontal line across the bottom refCairo->move_to( paddedLeft, paddedTop + paddedHeight ); refCairo->line_to( paddedLeft + paddedWidth, paddedTop + paddedHeight ); refCairo->stroke(); /* std::vector<double> dash_vector(2); dash_vector[0] = 1.0; dash_vector[1] = 2.0; refCairo->set_dash( dash_vector, 0.0 ); */ // Set line width refCairo->set_line_width(0.25); const int k_numPartitions = 8; for ( int i=1; i < k_numPartitions; i++ ) { const float fraction = i / static_cast<float>(k_numPartitions); // Draw vertical lines float xOffset = paddedLeft + (paddedWidth * fraction); refCairo->move_to( xOffset, paddedTop ); refCairo->line_to( xOffset, paddedTop + paddedHeight ); float yOffset = 0; if ( m_drawMode == Histogram::MODE_HISTOGRAM ) { if ( i % 2 != 0 ) { continue; } float scaleRatio = 100 / static_cast<float>(m_maxVal); yOffset = paddedTop + paddedHeight - (paddedHeight * fraction * scaleRatio); } else if ( m_drawMode == Histogram::MODE_ROWCOL ) { yOffset = paddedTop + paddedHeight - (paddedHeight * fraction); } if ( yOffset > paddedTop ) { refCairo->move_to( paddedLeft, yOffset ); refCairo->line_to( paddedLeft + paddedWidth, yOffset ); } } refCairo->stroke(); refCairo->restore(); }
void HistogramDrawingArea::DrawSingleHistogramLine( Cairo::RefPtr<Cairo::Context> refCairo, ImageStatistics::StatisticsChannel channel ) { unsigned int rangeMin, rangeMax, pixelValueMin, pixelValueMax; unsigned int numPixelValues; float pixelValueMean; int* pHistogram; m_histogramStats.GetStatistics( channel, &rangeMin, &rangeMax, &pixelValueMin, &pixelValueMax, &numPixelValues, &pixelValueMean, &pHistogram ); std::vector<float> percentages = GetPercentages( numPixelValues, pHistogram ); refCairo->save(); // Reserve the outside 10% float paddedLeft, paddedTop, paddedWidth, paddedHeight; GetPaddedSize( paddedLeft, paddedTop, paddedWidth, paddedHeight ); const float xScale = static_cast<float>(paddedWidth / numPixelValues); const float yScale = paddedHeight / static_cast<float>(m_maxVal); // Set draw color double red, green, blue; GetLineColor( channel, red, green, blue ); refCairo->set_source_rgb(red, green, blue); // Set line width refCairo->set_line_width(1.0); if ( numPixelValues > 256 ) { const int k_pixelsToAvg = static_cast<int>(numPixelValues / paddedWidth); for ( unsigned int i=0; i < numPixelValues; i += k_pixelsToAvg ) { float maxVal = 0.0; for ( int j=0; j < k_pixelsToAvg; j++ ) { if ( i+j >= numPixelValues ) { break; } if ( percentages[i+j] > maxVal ) { maxVal = percentages[i+j]; } } // Calculate the scaled height of the current percentage float yScaledHeight = yScale * maxVal; if ( i == 0 ) { refCairo->move_to( paddedLeft, (paddedTop + paddedHeight - yScaledHeight) ); } refCairo->line_to( paddedLeft + (xScale * i), paddedTop + paddedHeight - yScaledHeight ); } } else { for ( unsigned int i=0; i < numPixelValues; i++ ) { // Calculate the scaled height of the current percentage float yScaledHeight = yScale * percentages[i]; if ( i == 0 ) { refCairo->move_to( paddedLeft, (paddedTop + paddedHeight - yScaledHeight) ); } refCairo->line_to( paddedLeft + (xScale * i), paddedTop + paddedHeight - yScaledHeight ); } } refCairo->stroke(); // Overwrite anything that appears on the paddedTop section refCairo->rectangle( paddedLeft, 0, paddedWidth, paddedTop ); refCairo->set_source_rgb( 255, 255, 255 ); refCairo->set_operator( Cairo::OPERATOR_OVER ); refCairo->fill(); refCairo->restore(); }
UINT Chunk::GetSize() { return 8 + GetPaddedSize(size); }