Skip to content

Commit

Permalink
ADD: New file size comparison using LZ4 #13
Browse files Browse the repository at this point in the history
  • Loading branch information
spillerrec committed Jan 13, 2018
1 parent c6adfe3 commit 7a5d9d4
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 50 deletions.
6 changes: 3 additions & 3 deletions cgCompress.pro
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ INCLUDEPATH += .
CONFIG += console
QT += concurrent

LIBS += -lz
LIBS += -lz -llz4

# Input
HEADERS += src/Image.hpp src/Frame.hpp src/ImageSimilarities.hpp src/MultiImage.hpp src/Converter.hpp src/OraSaver.hpp src/FileUtils.hpp src/Format.hpp src/ProgressBar.hpp
SOURCES += src/Image.cpp src/Frame.cpp src/ImageSimilarities.cpp src/MultiImage.cpp src/Converter.cpp src/OraSaver.cpp src/FileUtils.cpp src/Format.cpp src/main.cpp
HEADERS += src/Image.hpp src/Frame.hpp src/ImageSimilarities.hpp src/MultiImage.hpp src/Converter.hpp src/OraSaver.hpp src/FileUtils.hpp src/Format.hpp src/FileSizeEval.hpp src/ProgressBar.hpp
SOURCES += src/Image.cpp src/Frame.cpp src/ImageSimilarities.cpp src/MultiImage.cpp src/Converter.cpp src/OraSaver.cpp src/FileUtils.cpp src/Format.cpp src/FileSizeEval.cpp src/main.cpp

# minizip
SOURCES += src/minizip/ioapi.cpp src/minizip/zip.cpp
Expand Down
112 changes: 112 additions & 0 deletions src/FileSizeEval.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
This file is part of cgCompress.
cgCompress is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cgCompress is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cgCompress. If not, see <http://www.gnu.org/licenses/>.
*/

#include "FileSizeEval.hpp"
#include "SubQImage.hpp"

#include <lz4.h>
#include <lz4hc.h>


static int compressed_lz4_size( const std::vector<uint8_t>& data ){
auto max_size = LZ4_compressBound( data.size() );
std::vector<uint8_t> buffer( max_size );

return LZ4_compress_HC(
(const char*)data.data(), (char*)buffer.data()
, data.size(), buffer.size()
, LZ4HC_DEFAULT_CLEVEL //TODO: Higher?
);
}


int FileSize::simple_alpha( QImage mask, int transparent ){
//TODO:
return 0;
}

/** Calculates the sum of the absolute difference between touching pixels
*
* \param [in] img Image to calculate for
* \return The computed value
*/
int FileSize::image_gradient_sum( QImage img ){
int diffs = 0;

auto w = img.width();
for( int iy=0; iy<img.height(); iy++ ){
auto row = (const QRgb*) img.constScanLine( iy );
for( int ix=1; ix<w/*img.width()*/; ix++ ){
//we add the difference in shown pixels
QRgb left = row[ix-1], right = row[ix];
diffs += abs( qAlpha(left) - qAlpha(right) );
if( ( qAlpha(left) > 0 ) && ( qAlpha(right) > 0 ) ){
diffs += abs( qRed(left) - qRed(right) );
diffs += abs( qGreen(left) - qGreen(right) );
diffs += abs( qBlue(left) - qBlue(right) );
}
}
}

return diffs;
}

int FileSize::image_gradient_sum( const SubQImage& img, QImage mask, int pixel_different ){
int diffs = 0;

auto w = img.width();
for( int iy=0; iy<img.height(); iy++ ){
auto row_alpha = mask.constScanLine( iy );
auto row = img.row( iy );
for( int ix=1; ix<w; ix++ ){
auto alpha_left = row_alpha[ix-1] != pixel_different;
auto alpha_right = row_alpha[ix ] != pixel_different;
diffs += (alpha_left != alpha_right) ? 255 : 0;
//TODO: not great for images with transparency
//we add the difference in shown pixels
if( !(alpha_left || alpha_right) ){
QRgb left = row[ix-1], right = row[ix];
diffs += abs( qRed( left) - qRed( right) );
diffs += abs( qGreen(left) - qGreen(right) );
diffs += abs( qBlue( left) - qBlue( right) );
}
}
}

return diffs;
}

int FileSize::lz4compress_size( QImage img ){
std::vector<uint8_t> data;
data.resize( img.width() * img.height() * 4 );

//Encode data
for( int iy=0; iy<img.height(); iy++ ){
auto row = (const QRgb*) img.constScanLine( iy );
for( int ix=0; ix<img.width(); ix++ ){
auto pos = iy*img.width()*4 + ix*4;
data[ pos + 0 ] = qRed( row[ix] );
data[ pos + 1 ] = qGreen( row[ix] );
data[ pos + 2 ] = qBlue( row[ix] );
data[ pos + 3 ] = qAlpha( row[ix] );
}
}

//Compress
auto size = compressed_lz4_size( data );
return size;
}
40 changes: 40 additions & 0 deletions src/FileSizeEval.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
This file is part of cgCompress.
cgCompress is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cgCompress is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cgCompress. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef FILE_SIZE_EVAL_HPP
#define FILE_SIZE_EVAL_HPP

#include <QImage>

/**
Several methods to guess how much space a image will take to store compressed.
However they are not compariable with final filesize or another metric
*/

class SubQImage;

namespace FileSize{

int simple_alpha( QImage mask, int transparent );
int image_gradient_sum( QImage img );
int image_gradient_sum( const SubQImage& img, QImage mask, int pixel_different );
int lz4compress_size( QImage img );

}

#endif

28 changes: 2 additions & 26 deletions src/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,10 @@
*/

#include "Format.hpp"
#include "FileSizeEval.hpp"

#include <QBuffer>

/** Calculates the sum of the absolute difference between touching pixels
*
* \param [in] img Image to calculate for
* \return The computed value
*/
int image_gradient_sum( QImage img ){
int diffs = 0;

auto w = img.width();
for( int iy=0; iy<img.height(); iy++ ){
auto row = (const QRgb*) img.constScanLine( iy );
for( int ix=1; ix<w/*img.width()*/; ix++ ){
//we add the difference in shown pixels
QRgb left = row[ix-1], right = row[ix];
diffs += abs( qAlpha(left) - qAlpha(right) );
if( ( qAlpha(left) > 0 ) && ( qAlpha(right) > 0 ) ){
diffs += abs( qRed(left) - qRed(right) );
diffs += abs( qGreen(left) - qGreen(right) );
diffs += abs( qBlue(left) - qBlue(right) );
}
}
}

return diffs;
}

/** Compress image to a memory buffer
*
Expand All @@ -66,7 +42,7 @@ QByteArray Format::to_byte_array( QImage img ) const{
*/
int Format::file_size( QImage img, Precision p ) const{
if( precision_level > 0 && p != HIGH )
return image_gradient_sum( img );
return FileSize::image_gradient_sum( img );
return to_byte_array( img ).size();
}

24 changes: 3 additions & 21 deletions src/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include "Image.hpp"
#include "FileSizeEval.hpp"

#include <cmath>

Expand Down Expand Up @@ -408,28 +409,9 @@ int Image::compressed_size( Format format, Format::Precision p ) const{
int Image::estimate_compressed_size( Format format ) const{
if( mask.isNull() )
return format.file_size( remove_transparent(), Format::LOW );
int diffs = 0;

auto w = img.width();
for( int iy=0; iy<img.height(); iy++ ){
auto row_alpha = mask.constScanLine( iy );
auto row = img.row( iy );
for( int ix=1; ix<w; ix++ ){
auto alpha_left = row_alpha[ix-1] != PIXEL_DIFFERENT;
auto alpha_right = row_alpha[ix ] != PIXEL_DIFFERENT;
diffs += (alpha_left != alpha_right) ? 255 : 0;
//TODO: not great for images with transparency
//we add the difference in shown pixels
if( !(alpha_left || alpha_right) ){
QRgb left = row[ix-1], right = row[ix];
diffs += abs( qRed( left) - qRed( right) );
diffs += abs( qGreen(left) - qGreen(right) );
diffs += abs( qBlue( left) - qBlue( right) );
}
}
}

return diffs;
return FileSize::image_gradient_sum( img, mask, PIXEL_DIFFERENT );
return FileSize::lz4compress_size( remove_transparent() );
}

bool Image::mustKeepAlpha() const{
Expand Down

0 comments on commit 7a5d9d4

Please sign in to comment.