VDPENC

Pagina 9/13
2 | 3 | 4 | 5 | 6 | 7 | 8 | | 10 | 11 | 12 | 13

Van ARTRAG

Enlighted (6933)

afbeelding van ARTRAG

23-05-2007, 00:55

New release of the screen 2 converter.

http://ragozini.googlepages.com/vdpenc.zip

Anyone willing to test it?
IMHO Jannone's conversions are still better (sc2 in the package), I do not know where I am wrong.

The CHR and CLR files now can be b-loaded in screen 2
e.g.
10 screen 2: color 15,0,0
20 bload"lenna_.CHR",s
30 bload"lenna_.CLR",s
40 goto 40

Van ARTRAG

Enlighted (6933)

afbeelding van ARTRAG

23-05-2007, 11:07

This is my code:


/*
---------------------------------------------------------------
TMSOPT v.0.04 - Eduardo A. Robsy Petrus & Arturo Ragozini, 2007
---------------------------------------------------------------
 TGA image converter (24 bpp, uncompressed) to TMS9918 format
---------------------------------------------------------------
Overview
---------------------------------------------------------------
Selects the best solution for each 8x1 pixel block
Optimization uses the following algorithm:

(a) Select one 1x8 block, compute the MSE wrt any couple of 
    allowed colors. 
    - All 105 combinations are tested.

(b) Apply Floyd-Steinberg quantizing the 1x8 block with the best
    two colors seleted at (a). 
    - Spread the errors on the adjacent points.

(c) repeat (a) and (b) on the next 1x8 block, scan all lines.

(d) Convert the image in pattern and color definitions (CHR & CLR) 

Load in MSX basic like this

10 screen 2: color 15,7,0
20 bload"FILE.CHR",s
30 bload"FILE.CLR",s
40 goto 40

---------------------------------------------------------------
Compilation instructions
---------------------------------------------------------------
 Tested with GCC/Win32 [mingw]:

   GCC TMSopt.c -oTMSopt.exe -O3 -s

 It is standard C, so there is a fair chance of being portable!
---------------------------------------------------------------
History
---------------------------------------------------------------
 Ages ago   - algorithm created
 16/05/2007 - first C version (RAW format)
 17/05/2007 - TGA format included, some optimization included
 18/05/2007 - Big optimization (200 times faster), support for
              square errors
 19/05/2007 - Floyd-Stenberg added, scaling for better rounding
---------------------------------------------------------------
Legal disclaimer
---------------------------------------------------------------
 Do whatever you want to do with this code/program.
 Use at your own risk, all responsability would be declined.
 It would be nice if you credit the author, though.
---------------------------------------------------------------
*/

// Headers!

#include<stdio.h>
#include<time.h>
#include<limits.h>

typedef unsigned int    uint;
typedef unsigned char   uchar;
typedef unsigned short  ushort;

//#define DEBUG

#define scale 16
#define inrange8(t) ((t)<0) ? 0 :(((t)>255) ? 255:(t))
#define clamp(t)    ((t)<0) ? 0 :(((t)>255*scale) ? 255*scale : (t))

// Just one function for everything

main(int argc, char **argv)
{

// Vars

 FILE *file,*CHR,*CLR;
 int bc,bp,i,j,x,y,c,p,k,MAXX,MAXY;
 uint n,total=0,done=0,size;
 char *name;
 short image[512+2][512+2][3],header[18],palette[16][3];

// TMS9918 RGB palette - approximated 50Hz PAL values
 uint pal[16][3]= {
{ 0,0,0},                 // 0 Transparent
{ 0,0,0},                 // 1 Black           0    0    0
{ 33,200,66},             // 2 Medium green   33  200   66
{ 94,220,120},            // 3 Light green    94  220  120
{ 84,85,237},             // 4 Dark blue      84   85  237
{ 125,118,252},           // 5 Light blue    125  118  252
{ 212,82,77},             // 6 Dark red      212   82   77
{ 66,235,245},            // 7 Cyan           66  235  245
{ 252,85,84},             // 8 Medium red    252   85   84
{ 255,121,120},           // 9 Light red     255  121  120
{ 212,193,84},            // A Dark yellow   212  193   84
{ 230,206,128},           // B Light yellow  230  206  128
{ 33,176,59},             // C Dark green     33  176   59
{ 201,91,186},            // D Magenta       201   91  186
{ 204,204,204},           // E Gray          204  204  204
{ 255,255,255}            // F White         255  255  255
};
// Scale palette

 for (i=0;i<16;i++)
     for (k=0;k<3;k++)
        palette[i][k] = scale*pal[i][k];

// Get time

 clock();

// Application prompt

 printf("TMSopt v.0.04 - TGA 24bpp to TMS9918 converter\nCoded by Eduardo A. Robsy Petrus & Arturo Ragozini, 2007\n");
// Test if only one command-line parameter is available

// Guess the name of the image I used for testing
#ifdef DEBUG
argc = 2;
argv[1] = malloc(20);
argv[1][0] = 'l';
argv[1][1] = 'e';
argv[1][2] = 'n';
argv[1][3] = 'n';
argv[1][4] = 'a';
argv[1][5] = '_';
argv[1][6] = '.';
argv[1][7] = 't';
argv[1][8] = 'g';
argv[1][9] = 'a';
argv[1][10] = 0;
#endif

 if (argc==1)
 {
  printf("Syntax: TMSopt [file.tga]\n");
  return;
 }

// Open source image (TGA, 24-bit, uncompressed)

 if ((file=fopen(argv[1],"rb"))==NULL)
 {
  printf("cannot open %s file!\n",argv[1]);
  return;
 }

// Read TGA header

 for (i=0;i<18;i++) header[i]=fgetc(file);

// Check header info

 for (i=0,n=0;i<12;i++) n+=header[i];

// I deleted the check on n, was it important ?
 if ((header[2]!=2)||(header[17])||(header[16]!=24))
 {
  printf("Unsupported file format!\n");
  return;
 }

// Calculate size

 MAXX=header[12]|header[13]<<8;
 MAXY=header[14]|header[15]<<8;

 size=((MAXX+7)>>3)*MAXY;

// Check size limits

 if ((!MAXX)||(MAXX>512)||(!MAXY)||(MAXY>512))
 {
  printf("Unsupported size!");
  return;
 }

// Load image data

 for (y=MAXY-1;y>=0;y--)
  for (x=0;x>3),((MAXY+7)>>3));


// Image processing


for (y=0;y<((MAXY+7)>>3);y++)
    for (j=0;j<8;j++)         
        for (x=0;x<((MAXX+7)>>3);x++)
         {
            // Generate alternatives
            uchar c1,c2;
            uint bs = INT_MAX;
//            uchar bp = 0;
            uchar bc = 0;

            uint yy = 1+((y<<3)|j);

            for (c1=1;c1<16;c1++)
                for (c2=c1+1;c2<16;c2++)
                {
                    uint    cs = 0;
//                    uchar    cp = 0;
                    for (i=0;i<8;i++)
                    {
                        uint xx = 1+((x<<3)|i);

                        short  u0 = (palette[c1][0]-image[xx][yy][0]);
                        short  u1 = (palette[c1][1]-image[xx][yy][1]);
                        short  u2 = (palette[c1][2]-image[xx][yy][2]);
                        uint  mc1 = u0*u0+u1*u1+u2*u2;

                        short  v0 = (palette[c2][0]-image[xx][yy][0]);
                        short  v1 = (palette[c2][1]-image[xx][yy][1]);
                        short  v2 = (palette[c2][2]-image[xx][yy][2]);
                        uint  mc2 = v0*v0+v1*v1+v2*v2;

//                        cp = (cp<<1) | (mc1>mc2);
                        cs += (mc1>mc2) ? mc2 : mc1;                        
                    }
                    if  (csmc2) ? bc2:bc1;

            for (k=0;k<3;k++)
            {
            // Compute the quantization error

               quant_error = (clamp(image[xx][yy][k]) - palette[newpixel][k])/16;

            // Store the current point - now quantized

               image[xx][yy][k] = palette[newpixel][k];

            // Spread the quantization error

               short q2 = quant_error<<1;
               image[xx+1][yy+1][k] = clamp(image[xx+1][yy+1][k])+ quant_error; // 1 *
		   quant_error += q2 ;
               image[xx-1][yy+1][k] = clamp(image[xx-1][yy+1][k])+ quant_error; // 3 *
		   quant_error += q2 ;
               image[xx+0][yy+1][k] = clamp(image[xx+0][yy+1][k])+ quant_error; // 5 *
		   quant_error += q2 ;
               image[xx+1][yy+0][k] = clamp(image[xx+1][yy+0][k])+ quant_error; // 7 *
            }
          }

            // Update status counter

          if (done*100/size<(done+1)*100/size)
             printf("\b\b\b%2i%%",100*done/size);
          done++;
          total++;
          }

// Conversion done

 printf("\b\b\bOk   \n");


// Create TMS output files (CHR, CLR)

 argv[1][strlen(argv[1])-3]='C';
 argv[1][strlen(argv[1])-2]='H';
 argv[1][strlen(argv[1])-1]='R';
 CHR=fopen(argv[1],"wb");

 argv[1][strlen(argv[1])-2]='L';
 CLR=fopen(argv[1],"wb");

fputc(0xFE,CLR);    // Binary data
fputc(0x00,CLR);    // Start at 2000h
fputc(0x20,CLR);
fputc(0xFF,CLR);    // Stop at 37FFh
fputc(0x37,CLR);
fputc(0x00,CLR);    // Run
fputc(0x00,CLR);


fputc(0xFE,CHR);    // Binary data
fputc(0x00,CHR);    // Start at 0000h
fputc(0x00,CHR);
fputc(0xFF,CHR);    // Stop at 17FFh
fputc(0x17,CHR);
fputc(0x00,CHR);    // Run
fputc(0x00,CHR);

            // Save best pattern and colour combination
   

 for (y=0;y<((MAXY+7)>>3);y++)
    for (x=0;(x<(MAXX+7)>>3);x++)
        for (j=0;j<8;j++)      
        {
            uchar c1,c2;
            uint bs = INT_MAX;
            uchar bp = 0, bc = 0;

            uint yy = 1+((y<<3)|j);

            for (c1=1;c1<16;c1++)
                for (c2=c1+1;c2<16;c2++)
                {
                    uint    cs = 0;
                    uint    cp = 0;
                    for (i=0;i<8;i++)
                    {
                        uint xx = 1+((x<<3)|i);

                        short  u0 = (palette[c1][0]-image[xx][yy][0]);
                        short  u1 = (palette[c1][1]-image[xx][yy][1]);
                        short  u2 = (palette[c1][2]-image[xx][yy][2]);
                        uint  mc1 = u0*u0+u1*u1+u2*u2;

                        short  v0 = (palette[c2][0]-image[xx][yy][0]);
                        short  v1 = (palette[c2][1]-image[xx][yy][1]);
                        short  v2 = (palette[c2][2]-image[xx][yy][2]);
                        uint  mc2 = v0*v0+v1*v1+v2*v2;

                        cp = (cp<<1) | (mc1>mc2);
                        cs += (mc1>mc2) ? mc2 : mc1;
                    }
                    if  (cs=0;y--)
  for (x=0;x		

Van ARTRAG

Enlighted (6933)

afbeelding van ARTRAG

24-05-2007, 12:55

All problems solved thanks to Rafael Jannone itself:
here the full package
http://ragozini.googlepages.com/dithering

Van Hecatonchire

Supporter (11)

afbeelding van Hecatonchire

24-05-2007, 15:10

so, what was the prob ? we want to know

( ARTRAG, i have a prob with your archive scr2_release01.rar, i just see a png)

Van ARTRAG

Enlighted (6933)

afbeelding van ARTRAG

24-05-2007, 15:23

My coder was optimizing the two colors on the 8 pixel block without applying the dithering (look in the code above).
Jannone's one (and my latest version) optimizes the two colors applying the dithering, so each two colors, apply
Floyd to the 8 pixels, evaluate the squared error, repeat for all the couples of colors (105 times), keep those with
the MSE.
Once you get the best colors apply the whole Floyd on the image.

Try now, I deleted a lot of test samples, now it is ligther

Van Huey

Prophet (2694)

afbeelding van Huey

24-05-2007, 16:14

Great work!
Can't wait to see some optimized movies........

Van Hecatonchire

Supporter (11)

afbeelding van Hecatonchire

24-05-2007, 17:56

yeah great work, i changed my code too, it works !!!!
(but my code is very slow, because i wrote it using REBOL scripting language)

Van ARTRAG

Enlighted (6933)

afbeelding van ARTRAG

24-05-2007, 18:49

Great work!
Can't wait to see some optimized movies........

Hi Huey,
moving the whole video encoder to C would take too much time.
Nevertheless I will include the scr2 converter in the Kmeans calling
my code from matlab (the result should be to an improved video encoder
with a reasonable coding speed, even if working only as matlab script)
and than go back to our game.

Van Huey

Prophet (2694)

afbeelding van Huey

24-05-2007, 22:08


and than go back to our game.

Hannibal Yesssssss Hannibal

Van ARTRAG

Enlighted (6933)

afbeelding van ARTRAG

26-05-2007, 17:35

New algorithm online with perceptually uniform distances in the color space

http://ragozini.googlepages.com/dithering

/*
---------------------------------------------------------------
TMSOPT v.0.1 - Eduardo A. Robsy Petrus & Arturo Ragozini 2007
Credits to Rafael Jannone for his Floyd-Steinberg implementation
---------------------------------------------------------------
 TGA image converter (24 bpp, uncompressed) to TMS9918 format
---------------------------------------------------------------
Overview
---------------------------------------------------------------
Selects the best solution for each 8x1 pixel block
Optimization uses the following algorithm:

(a) Select one 1x8 block, select a couple of colors, apply
    Floyd-Steinberg within the block, compute the squared error,
    repeat for all 105 color combinations, keep the best couple
    of colors.

(b) Apply Floyd-Steinberg to the current 1x8 block with the best
    two colors selected before and spread the errors to the
    adjacent blocks.

(c) repeat (a) and (b) on the next 1x8 block, scan all lines.

(d) Convert the image in pattern and color definitions (CHR & CLR)

To load in MSX basic use something like this:

10 screen 2: color 15,0,0
20 bload"FILE.CHR",s
30 bload"FILE.CLR",s
40 goto 40

---------------------------------------------------------------
Compilation instructions
---------------------------------------------------------------
 Tested with GCC/Win32 [mingw]:

   GCC TMSopt.c -oTMSopt.exe -O3 -s

 It is standard C, so there is a fair chance of being portable!
 NOTE
 In the current release the name of the C file has become scr2floyd.c
---------------------------------------------------------------
History
---------------------------------------------------------------
 Ages ago   - algorithm created
 16/05/2007 - first C version (RAW format)
 17/05/2007 - TGA format included, some optimization included
 18/05/2007 - Big optimization (200 times faster), support for
              square errors
 19/05/2007 - Floyd-Stenberg added, scaling for better rounding
 24/05/2007 - Floyd-Stenberg included in the color optimization.
---------------------------------------------------------------
Legal disclaimer
---------------------------------------------------------------
 Do whatever you want to do with this code/program.
 Use at your own risk, all responsability would be declined.
 It would be nice if you credit the authors, though.
---------------------------------------------------------------
*/

// Headers!

#include<stdio.h>
#include<time.h>
#include<limits.h>

typedef unsigned int    uint;
typedef unsigned char   uchar;
typedef unsigned short  ushort;
typedef unsigned long   ulong;

//#define DEBUG

#define scale 16
#define inrange8(t) ((t)<0) ? 0 :(((t)>255) ? 255:(t))
#define clamp(t)    ((t)<0) ? 0 :(((t)>255*scale) ? 255*scale : (t))


typedef struct {
   float r, g, b;
} RGB;

float ColourDistance(RGB e1, RGB e2)
{
  float r,g,b;
  float rmean;
 
  e1.r/=scale;
  e1.g/=scale;   
  e1.b/=scale;   
 
  e2.r/=scale;
  e2.g/=scale;   
  e2.b/=scale;   

  rmean = ( (int)e1.r + (int)e2.r ) / 2 ;
  r = ((int)e1.r - (int)e2.r);
  g = ((int)e1.g - (int)e2.g);
  b = ((int)e1.b - (int)e2.b);
//  return r*r+g*g+b*b;
  return ((((512+rmean)*r*r)/256) + 4*g*g + (((767-rmean)*b*b)/256));
}

// Just one function for everything

main(int argc, char **argv)
{

// Vars

 FILE *file,*CHR,*CLR;
 int bc,bp,i,j,x,y,c,p,k,MAXX,MAXY;
 uint n,total=0,done=0,size;
 char *name;
 short image[512+2][512+2][3],header[18],palette[16][3];

// TMS9918 RGB palette - approximated 50Hz PAL values
 uint pal[16][3]= {
{ 0,0,0},                 // 0 Transparent
{ 0,0,0},                 // 1 Black           0    0    0
{ 33,200,66},             // 2 Medium green   33  200   66
{ 94,220,120},            // 3 Light green    94  220  120
{ 84,85,237},             // 4 Dark blue      84   85  237
{ 125,118,252},           // 5 Light blue    125  118  252
{ 212,82,77},             // 6 Dark red      212   82   77
{ 66,235,245},            // 7 Cyan           66  235  245
{ 252,85,84},             // 8 Medium red    252   85   84
{ 255,121,120},           // 9 Light red     255  121  120
{ 212,193,84},            // A Dark yellow   212  193   84
{ 230,206,128},           // B Light yellow  230  206  128
{ 33,176,59},             // C Dark green     33  176   59
{ 201,91,186},            // D Magenta       201   91  186
{ 204,204,204},           // E Gray          204  204  204
{ 255,255,255}            // F White         255  255  255
};
// Scale palette

 for (i=0;i<16;i++)
     for (k=0;k<3;k++)
        palette[i][k] = scale*pal[i][k];

// Get time

 clock();

// Application prompt

 printf("TMSopt v.0.1 - TGA 24bpp to TMS9918 converter.\nCoded by Eduardo A. Robsy Petrus & Arturo Ragozini 2007.\n\n");
 printf("Credits to Rafael Jannone for his Floyd-Steinberg implementation.\n \n");


// Guess the name of the image I used for testing
#ifdef DEBUG
argc = 2;
argv[1] = malloc(20);
argv[1][0] = 'l';
argv[1][1] = 'e';
argv[1][2] = 'n';
argv[1][3] = 'n';
argv[1][4] = 'a';
argv[1][5] = '_';
argv[1][6] = '.';
argv[1][7] = 't';
argv[1][8] = 'g';
argv[1][9] = 'a';
argv[1][10] = 0;
#endif

// Test if only one command-line parameter is available

 if (argc==1)
 {
  printf("Syntax: TMSopt [file.tga]\n");
  return;
 }

// Open source image (TGA, 24-bit, uncompressed)

 if ((file=fopen(argv[1],"rb"))==NULL)
 {
  printf("cannot open %s file!\n",argv[1]);
  return;
 }

// Read TGA header

 for (i=0;i<18;i++) header[i]=fgetc(file);

// Check header info

 for (i=0,n=0;i<12;i++) n+=header[i];

// I deleted the check on n, was it important ?
 if ((header[2]!=2)||(header[17])||(header[16]!=24))
 {
  printf("Unsupported file format!\n");
  return;
 }

// Calculate size

 MAXX=header[12]|header[13]<<8;
 MAXY=header[14]|header[15]<<8;

 size=((MAXX+7)>>3)*MAXY;

// Check size limits

 if ((!MAXX)||(MAXX>512)||(!MAXY)||(MAXY>512))
 {
  printf("Unsupported size!");
  return;
 }

// Load image data

 for (y=MAXY-1;y>=0;y--)
  for (x=0;x>3),((MAXY+7)>>3));


// Image processing

for (y=0;y<((MAXY+7)>>3);y++)
    for (j=0;j<8;j++)
        for (x=0;x<((MAXX+7)>>3);x++)
        {
            // Generate alternatives
            uchar  c1,  c2;
            uchar bc1, bc2;
            uint  bv;
            uint  bs = INT_MAX;

            uint  yy = 1+((y<<3)|j);

            for (c1=1;c1<16;c1++)
            {
                RGB cp1 = {palette[c1][0],palette[c1][1],palette[c1][2]};

                for (c2=c1+1;c2<16;c2++)
                {
                    RGB cp2 = {palette[c2][0],palette[c2][1],palette[c2][2]};

                    uint xx = 1+(x<<3);
                                       
                    RGB ppp = {clamp(image[xx][yy][0]),clamp(image[xx][yy][1]),clamp(image[xx][yy][2])};

                    uint  cs = 0;
                    uint  cv = 0;

                    for (i=0;i<8;i++)
                    {
                        short  e10 = (ppp.r-cp1.r);
                        short  e11 = (ppp.g-cp1.g);
                        short  e12 = (ppp.b-cp1.b);
                        long   mc1 = ColourDistance(cp1,ppp);

                        short  e20 = (ppp.r-cp2.r);
                        short  e21 = (ppp.g-cp2.g);
                        short  e22 = (ppp.b-cp2.b);
                        long   mc2 = ColourDistance(cp2,ppp);

                        cs += (mc1>mc2) ? mc2 : mc1;

                        if (cs>bs) break;

                        cv |= ((mc1>mc2)<mc2)
                        {
                            ppp.r = clamp(image[xx][yy][0]) + 7*e20/16;
                            ppp.g = clamp(image[xx][yy][1]) + 7*e21/16;
                            ppp.b = clamp(image[xx][yy][2]) + 7*e22/16;
                        }
                        else
                        {
                            ppp.r = clamp(image[xx][yy][0]) + 7*e10/16;
                            ppp.g = clamp(image[xx][yy][1]) + 7*e11/16;
                            ppp.b = clamp(image[xx][yy][2]) + 7*e12/16;
                        }
                    }
                    if  (cs3);y++)
    for (x=0;(x<(MAXX+7)>>3);x++)
        for (j=0;j<8;j++)
        {
            uchar c1,c2;
            uint bs = INT_MAX;
            uchar bp = 0, bc = 0;

            uint yy = 1+((y<<3)|j);

            for (c1=1;c1<16;c1++)
            {
                RGB cp1 = {palette[c1][0],palette[c1][1],palette[c1][2]};
                for (c2=c1+1;c2<16;c2++)
                {
                    RGB cp2 = {palette[c2][0],palette[c2][1],palette[c2][2]};
                    uint    cs = 0;
                    uint    cp = 0;
                    for (i=0;i<8;i++)
                    {
                        uint xx = 1+((x<<3)|i);
                        RGB ppp = {clamp(image[xx][yy][0]),clamp(image[xx][yy][1]),clamp(image[xx][yy][2])};

                        long   mc1 = ColourDistance(cp1,ppp);
                        long   mc2 = ColourDistance(cp2,ppp);

                        cp = (cp<<1) | (mc1>mc2);
                        cs += (mc1>mc2) ? mc2 : mc1;
                        if (cs>bs) break;
                    }
                    if  (cs=0;y--)
  for (x=0;x		
Pagina 9/13
2 | 3 | 4 | 5 | 6 | 7 | 8 | | 10 | 11 | 12 | 13