It was me, who optimized the PCX file usage of QBPDraw. I will write here now how i did it
First of all I noticed a bug in the loader of version 1.6: it cut down the right - and the bottom line of the loaded PCX files. After fixing this i started testing the sizes of the output images with all of my programs what could create PCX files. Here are the results:
(All the files were 16 colors including the input ones, so the programs only did the coding, but changing anything on the image.)
Code:
File 1: An image converted from JPG
PictView 74813
Deluxe Paint II 76899
Display 74831
QBPDraw 1.6 75895
File 2: A drawing with large blocks of compressable data
PictView 17019
Deluxe Paint II 20174
Display 17675
QBPDraw 1.6 17144
My first idea was inserting this code in the scan line generation part:
(It makes the unused bytes similar to the last used)
Code:
IF j * 8 >= bmpsiz(0) THEN
scl(j) = scl(j - 1)
scl(j + sx2) = scl(j + sx2 - 1)
scl(j + 2 * sx2) = scl(j + 2 * sx2 - 1)
scl(j + 3 * sx2) = scl(j + 3 * sx2 - 1)
END IF
Then these values got:
Code:
File 1
QBPDraw (tweak1) 75540
File 2
QBPDraw (tweak1) 17258
In the first case the file size lowered as expected, but with the drawing it increased. This must have happened because the next line started with zero bytes and those unused ones were zeros too, but the last used bytes stood alone. This method increased that size wich resulted an one byte loss at (because sometimes single bytes can be compressed into 1 byte). To prevent this i tried this more complex code:
Code:
'Optimizing scan line for compression
unused = sx2 - INT((bmpsiz(0) + 7) / 8)
'Unused bytes at the end of each plane
IF unused > 0 THEN
FOR k = 0 TO 3
IF k < 3 AND sx2 > 1 THEN
s1 = scl(sx2 * (k + 1) - 1 - unused) 'End of used part of plane
s2 = scl(sx2 * (k + 1) - 2 - unused)
s3 = scl(sx2 * (k + 1)) 'Start of new plane
s4 = scl(sx2 * (k + 1) + 1)
IF ((s1 = s2) AND (s3 = s4)) OR ((s1 <> s2) AND (s3 <> s4)) THEN
IF s1 < 128 + 64 THEN col = s3 ELSE col = s1
ELSE
IF (s1 = s2) THEN col = s1 ELSE col = s3
END IF
ELSE
col = scl(sx2 * (k + 1) - 1 - unused)
END IF
FOR j = 1 TO unused
scl(sx2 * (k + 1) - j) = col
NEXT j
NEXT k
END IF
After this tweaking these sizes were achieved:
Code:
File 1
QBPDraw (tweak2) 75369
File 2
QBPDraw (tweak2) 17139
These results were much better. But there is an other way to make the compression better: to try to similarize the halfly used bytes to the ones before them, so if succeed they can be compressed. This code was able to do that (of course with keeping tweak2):
Code:
IF j * 8 + k >= bmpsiz(0) THEN
FOR s1 = 0 TO 3
scl(j + sx2 * s1) = scl(j + sx2 * s1) OR (scl(j + sx2 * s1 - 1) AND l)
NEXT s1
END IF
The results:
Code:
File 1
QBPDraw (tweak3) 75369
File 2
QBPDraw (tweak3) 16980
I was very surprised with the second value: it was smaller than all of my viewers' sizes! First i thought that i made something wrong, but not, the image was coded well.
The final results (by treating PictView's size as 100%):
Code:
File 1:
PictView 74813 100,00%
Deluxe Paint II 76899 102,79%
Display 74831 100,02%
QBPDraw 1.6 75895 101,45%
QBPDraw (tweak1) 75540 100,97%
QBPDraw (tweak2) 75369 100,74%
QBPDraw (tweak3) 75369 100,74%
File 2:
PictView 17019 100,00%
Deluxe Paint II 20174 118,54%
Display 17675 103,85%
QBPDraw 1.6 17144 100,73%
QBPDraw (tweak1) 17258 101,40%
QBPDraw (tweak2) 17139 100,71%
QBPDraw (tweak3) 16980 99,77% (!)
The compression method of tweak3 might be optimized only by finding out somehow to where those halfly filled bytes should be similarized: to the next scanline's first one or to the last one from the current scanline. I did not do that since it was very complex, and i was tired. So QBPDraw 1.7 was created with tweak3.
There were a small difference in the PCX files created by QBPDraw or Deluxe Paint II to Display or PictView: although all of them generated 4 plane PCXs, the last two did not keep the width of the scan line dividable by 2. QBPDraw could open all of the generated PCX files without any problem. Possibly this was why QBPDraw created sometimes bigger and sometimes smaller files than theirs.
Some other files tried with PictView and QBPDraw (tweak3):
Code:
PictView QBPDraw
JPG Image 52333 52406 100,14%
JPG Image* 2578 2578 100,00%
Image** 1777 1804 101,52%
Drawing* 9021 9021 100,00%
Drawing 18228 17548 96,27%
Drawing 7259 6784 93,45%
File 1 74813 75369 100,74%
File 2 17019 16980 99,77%
*: It had a width dividable by 16 so none of the optimizations used.
**: A JPG style image with huge areas of one colored background.
As i could remember all of the files where QBPDraw created larger files than the others had sizes from k * 8 + 1 to k * 8 + 8 so PictView created odd number sized planes but QBPDraw so it had to process the unused bytes somehow what resulted larger sizes.