diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2019-03-26 18:33:17 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2019-03-26 18:33:17 (GMT) |
commit | 7f627a590e68e9be3cb5d80c751cd179a9122a9c (patch) | |
tree | 3d3ee79087a4e243e4edae882e21fdd0b1988437 | |
parent | 1ca5e80bc7e86e682ff04ea09e32f9f817bdda4c (diff) | |
parent | f5c77c2e3ccd6015e5948b914f9e6a40c94f357a (diff) | |
download | blt-7f627a590e68e9be3cb5d80c751cd179a9122a9c.zip blt-7f627a590e68e9be3cb5d80c751cd179a9122a9c.tar.gz blt-7f627a590e68e9be3cb5d80c751cd179a9122a9c.tar.bz2 |
Merge branch 'devel'
-rw-r--r-- | ds9/library/movie.tcl | 4 | ||||
-rw-r--r-- | tkagif/tkagif.C | 441 | ||||
-rw-r--r-- | tkagif/tkagif.h | 22 |
3 files changed, 284 insertions, 183 deletions
diff --git a/ds9/library/movie.tcl b/ds9/library/movie.tcl index 88f23b6..9dc2922 100644 --- a/ds9/library/movie.tcl +++ b/ds9/library/movie.tcl @@ -339,10 +339,10 @@ proc MoviePhotoGIF {} { if {$movie(first)} { switch [$current(frame) get type] { rgb { - agif create $movie(fn) [image width $ph] [image height $ph] 16 + agif create $movie(fn) [image width $ph] [image height $ph] } default { - agif create $movie(fn) [image width $ph] [image height $ph] 4 + agif create $movie(fn) [image width $ph] [image height $ph] } } set movie(first) 0 diff --git a/tkagif/tkagif.C b/tkagif/tkagif.C index dcd3e4c..2f63474 100644 --- a/tkagif/tkagif.C +++ b/tkagif/tkagif.C @@ -21,19 +21,6 @@ extern "C" { const char* argv[]); } -typedef struct { - int count; - unsigned char red; - unsigned char green; - unsigned char blue; -} Color; - -typedef struct { - unsigned char red; - unsigned char green; - unsigned char blue; -} Pixel; - TkAGIF* tkagif=NULL; int Tkagif_Init(Tcl_Interp* interp) { @@ -84,15 +71,15 @@ TkAGIF::TkAGIF(Tcl_Interp* interp) out_ =NULL; width_ = 512; height_ = 512; - colorRes_ = 4; // pseudocolor - //colorRes_ = 16; // rgb + resolution_ =0; // state vars - colorTableSize_ =0; - resolution_ =0; pict_ =NULL; pictCount_ =0; + colorTable_ =NULL; + colorTableSize_ =0; + // Compress initialBits_ =0; numBits_ =0; @@ -111,14 +98,14 @@ TkAGIF::TkAGIF(Tcl_Interp* interp) int TkAGIF::create(int argc, const char* argv[]) { - if (argc == 6) { + if (argc == 5) { if (*argv[2] == '\0') { Tcl_AppendResult(interp_, "bad filename", NULL); return TCL_ERROR; } } else { - Tcl_AppendResult(interp_, "usage: tkagif create <filename> <width> <height> <color resolution> ", NULL); + Tcl_AppendResult(interp_, "usage: tkagif create <filename> <width> <height>", NULL); return TCL_ERROR; } @@ -141,11 +128,6 @@ int TkAGIF::create(int argc, const char* argv[]) istringstream str(s); str >> height_; } - { - string s(argv[5]); - istringstream str(s); - str >> colorRes_; - } // *** Header *** { @@ -287,8 +269,6 @@ static int cmpColor(const void* a, const void* b) return 1; } -#define ALMOST(aa,bb) (abs(aa-bb) <= colorRes_ ? 1 : 0) - int TkAGIF::add(int argc, const char* argv[]) { if (argc == 3) { @@ -302,47 +282,6 @@ int TkAGIF::add(int argc, const char* argv[]) return TCL_ERROR; } - // colortable - int maxColors = 4096; - int totalColors =11; - Color cc[maxColors]; - memset(cc,0,sizeof(Color)*maxColors); - - // Base Colors - // 0: black - // 1: white - cc[1].red = cc[1].green = cc[1].blue = 255; - cc[1].count++; - // 2: red - cc[2].red = 255; - cc[2].count++; - // 3: green - cc[3].green = 255; - cc[3].count++; - // 4: blue - cc[4].blue = 255; - cc[4].count++; - // 5: cyan - cc[5].green = cc[5].blue = 255; - cc[5].count++; - // 6: magenta - cc[6].red = cc[6].blue = 255; - cc[6].count++; - // 7: yellow - cc[7].red = cc[7].green = 255; - cc[7].count++; - - // some Greys for numerics - // 8: 1/4 grey - cc[8].red = cc[8].green = cc[8].blue = 64; - cc[8].count++; - // 9: 1/2 grey - cc[9].red = cc[9].green = cc[9].blue = 128; - cc[9].count++; - // 10: 3/4 grey - cc[10].red = cc[10].green = cc[10].blue = 192; - cc[10].count++; - // RGB img Pixel* pixels = new Pixel[width_*height_]; memset(pixels,0,sizeof(Pixel)*width_*height_); @@ -368,7 +307,238 @@ int TkAGIF::add(int argc, const char* argv[]) } } } + + // Indexed img + if (pict_) + delete [] pict_; + pict_ =NULL; + pictCount_ =0; + + pict_ = new unsigned char[width_*height_]; + memset(pict_,0,width_*height_); + + //alg1(pixels); + alg2(pixels); + + // *** Local Image Descriptor *** + { + // Image Separator + unsigned char img= 0x2C; + out_->write((char*)&img,1); + + // Image Left Position + unsigned short left = 0; + out_->write((char*)&left,2); + + // Image Top Position + unsigned short top = 0; + out_->write((char*)&top,2); + + // Image Width + unsigned short ww = width_; + out_->write((char*)&ww,2); + + // Image Heght + unsigned short hh = height_; + out_->write((char*)&hh,2); + + // Packed Field msb to lsb + // Local Table Flag (1): 1 local table, 0 no + // Interlace Flag (1): 1 interlaced, 0 no + // Sort Flag (1): 1 sorted, 0 no + // Reserved (2): + // Size of Local Table (3): size 2^(x+1) + union qq { + struct pp { + unsigned int size: 3; + unsigned int reserve: 2; + unsigned int sort: 1; + unsigned int interlace: 1; + unsigned int ct: 1; + } tt; + unsigned char cc; + }; + union qq pkg; + + pkg.tt.ct = 1; + pkg.tt.interlace =0; + pkg.tt.sort = 0; + pkg.tt.reserve = 0; + pkg.tt.size = resolution_-1; + + out_->write((char*)&pkg.cc,1); + } + + // *** Local Color Table *** + for (int ii=0; ii<colorTableSize_; ii++) { + out_->write((char*)&colorTable_[ii].red,1); + out_->write((char*)&colorTable_[ii].green,1); + out_->write((char*)&colorTable_[ii].blue,1); + } + + // *** Image Data *** + // noCompress(); + compress(); + // end of Image Data + unsigned char end= 0x00; + out_->write((char*)&end,1); + + // cleanup + if (pict_) + delete [] pict_; + pict_ =NULL; + pictCount_ =0; + + if (colorTable_) + delete [] colorTable_; + colorTable_ =NULL; + + return TCL_OK; +} + +int TkAGIF::close(int argc, const char* argv[]) +{ + // *** Trailer *** + unsigned char end = 0x3B; + out_->write((char*)&end,1); + + out_->close(); + delete out_; + + return TCL_OK; +} + +void TkAGIF::initColorTable(Color* ct) +{ + // Base Colors + // 0: black + // 1: white + ct[1].red = ct[1].green = ct[1].blue = 255; + ct[1].count++; + // 2: red + ct[2].red = 255; + ct[2].count++; + // 3: green + ct[3].green = 255; + ct[3].count++; + // 4: blue + ct[4].blue = 255; + ct[4].count++; + // 5: cyan + ct[5].green = ct[5].blue = 255; + ct[5].count++; + // 6: magenta + ct[6].red = ct[6].blue = 255; + ct[6].count++; + // 7: yellow + ct[7].red = ct[7].green = 255; + ct[7].count++; + + // some Greys for numerics + // 8: 1/4 grey + ct[8].red = ct[8].green = ct[8].blue = 64; + ct[8].count++; + // 9: 1/2 grey + ct[9].red = ct[9].green = ct[9].blue = 128; + ct[9].count++; + // 10: 3/4 grey + ct[10].red = ct[10].green = ct[10].blue = 192; + ct[10].count++; +} + +#define ALMOST2(aa,bb) (abs(aa-bb) <= iter) + +void TkAGIF::alg2(Pixel* pixels) +{ + int maxColors = 256; + + int finished =0; + int iter = 1; + int totalColors =11; + + if (colorTable_) + delete [] colorTable_; + colorTable_ = new Color[maxColors]; + + initColorTable(colorTable_); + + do { + totalColors =11; + memset(&colorTable_[totalColors],0,sizeof(Color)*(maxColors-totalColors)); + + Pixel* src = pixels; + unsigned char* dst = pict_; + for (int jj=0; jj<height_; jj++) { + for (int ii=0; ii<width_; ii++, src++, dst++) { + // first try all known colors + int done =0; + for (int kk=0; kk<totalColors; kk++) { + if (ALMOST2(src->red, colorTable_[kk].red) && + ALMOST2(src->green, colorTable_[kk].green) && + ALMOST2(src->blue, colorTable_[kk].blue)) { + colorTable_[kk].count++; + *dst = kk; + done =1; + break; + } + } + + // add color + if (!done) { + if (totalColors<maxColors) { + colorTable_[totalColors].red = src->red; + colorTable_[totalColors].green = src->green; + colorTable_[totalColors].blue = src->blue; + colorTable_[totalColors].count++; + *dst = totalColors; + totalColors++; + } + else { + // abort, try again + iter ++; + goto end; + } + } + } + } + finished =1; + + end: + ; + } while (!finished); + + resolution_ =0; + while (totalColors >> resolution_) + resolution_++; + if (resolution_>8) + resolution_ =8; + colorTableSize_ = 1 << resolution_; + + if (0) { + cerr << "Iteration: " << iter << endl; + cerr << "Total Colors: " << totalColors << endl; + cerr << "Resolution: " << resolution_ << endl; + cerr << "ColorTableSize: " << colorTableSize_ << endl; + for (int ii=0; ii<totalColors; ii++) { + cerr << ii << ' ' + << colorTable_[ii].count << ' ' + << (unsigned short)(colorTable_[ii].red) << ' ' + << (unsigned short)colorTable_[ii].green << ' ' + << (unsigned short)colorTable_[ii].blue << endl; + } + } +} + +void TkAGIF::alg1(Pixel* pixels) +{ + int totalColors =11; + int maxColors = 4096; + Color cc[maxColors]; + memset(cc,0,sizeof(Color)*maxColors); + + initColorTable(cc); + // Scan and sort all colors { Pixel* dst = pixels; @@ -377,9 +547,9 @@ int TkAGIF::add(int argc, const char* argv[]) // first try all known colors int done =0; for (int kk=0; kk<totalColors; kk++) { - if (ALMOST(dst->red, cc[kk].red) && - ALMOST(dst->green, cc[kk].green) && - ALMOST(dst->blue, cc[kk].blue)) { + if (dst->red == cc[kk].red && + dst->green == cc[kk].green && + dst->blue == cc[kk].blue) { cc[kk].count++; done =1; break; @@ -411,6 +581,9 @@ int TkAGIF::add(int argc, const char* argv[]) resolution_ =8; colorTableSize_ = 1 << resolution_; + cerr << "Resolution: " << resolution_ << endl; + cerr << "ColorTableSize: " << colorTableSize_ << endl; + cerr << "Total Colors: " << totalColors << endl; if (0) { cerr << "Resolution: " << resolution_ << endl; cerr << "ColorTableSize: " << colorTableSize_ << endl; @@ -425,35 +598,28 @@ int TkAGIF::add(int argc, const char* argv[]) } // build colortable - Color ct[colorTableSize_]; - memset(ct,0,sizeof(Color)*colorTableSize_); + colorTable_ = new Color[colorTableSize_]; + memset(colorTable_,0,sizeof(Color)*colorTableSize_); for (int ii=0; ii<colorTableSize_; ii++) { - ct[ii].count = cc[ii].count; - ct[ii].red = cc[ii].red; - ct[ii].green = cc[ii].green; - ct[ii].blue = cc[ii].blue; + colorTable_[ii].count = cc[ii].count; + colorTable_[ii].red = cc[ii].red; + colorTable_[ii].green = cc[ii].green; + colorTable_[ii].blue = cc[ii].blue; } if (0) { cerr << "ColorTable Size: " << colorTableSize_ << endl; for (int ii=0; ii<colorTableSize_; ii++) { cerr << ii << ' ' - << ct[ii].count << ' ' - << (unsigned short)(ct[ii].red) << ' ' - << (unsigned short)ct[ii].green << ' ' - << (unsigned short)ct[ii].blue << endl; + << colorTable_[ii].count << ' ' + << (unsigned short)(colorTable_[ii].red) << ' ' + << (unsigned short)colorTable_[ii].green << ' ' + << (unsigned short)colorTable_[ii].blue << endl; } } // now indexed image - if (pict_) - delete [] pict_; - pict_ =NULL; - pictCount_ =0; - - pict_ = new unsigned char[width_*height_]; - memset(pict_,0,width_*height_); { Pixel* src = pixels; unsigned char* dst = pict_; @@ -463,9 +629,9 @@ int TkAGIF::add(int argc, const char* argv[]) // first try all known colors int done =0; for (int kk=0; kk<colorTableSize_; kk++) { - if (ALMOST(src->red, ct[kk].red) && - ALMOST(src->green, ct[kk].green) && - ALMOST(src->blue, ct[kk].blue)) { + if (src->red == colorTable_[kk].red && + src->green == colorTable_[kk].green && + src->blue == colorTable_[kk].blue) { *dst = (unsigned char)kk; done =1; break; @@ -477,10 +643,13 @@ int TkAGIF::add(int argc, const char* argv[]) int id =0; double dd =FLT_MAX; for (int kk=0; kk<colorTableSize_; kk++) { - double vv = - pow((src->red - ct[kk].red) *.3,2) + - pow((src->green - ct[kk].green) *.59,2) + - pow((src->blue - ct[kk].blue) *.11,2); + double rr = (src->red - colorTable_[kk].red); + double gg = (src->green - colorTable_[kk].green); + double bb = (src->blue - colorTable_[kk].blue); + // double rr = (src->red - colorTable_[kk].red)*.3; + // double gg = (src->green - colorTable_[kk].green)*.59; + // double bb = (src->blue - colorTable_[kk].blue)*.11; + double vv = sqrt(rr*rr+gg*gg+bb*bb); if (vv<dd) { id = kk; dd = vv; @@ -491,90 +660,6 @@ int TkAGIF::add(int argc, const char* argv[]) } } } - - // *** Local Image Descriptor *** - { - // Image Separator - unsigned char img= 0x2C; - out_->write((char*)&img,1); - - // Image Left Position - unsigned short left = 0; - out_->write((char*)&left,2); - - // Image Top Position - unsigned short top = 0; - out_->write((char*)&top,2); - - // Image Width - unsigned short ww = width_; - out_->write((char*)&ww,2); - - // Image Heght - unsigned short hh = height_; - out_->write((char*)&hh,2); - - // Packed Field msb to lsb - // Local Table Flag (1): 1 local table, 0 no - // Interlace Flag (1): 1 interlaced, 0 no - // Sort Flag (1): 1 sorted, 0 no - // Reserved (2): - // Size of Local Table (3): size 2^(x+1) - union qq { - struct pp { - unsigned int size: 3; - unsigned int reserve: 2; - unsigned int sort: 1; - unsigned int interlace: 1; - unsigned int ct: 1; - } tt; - unsigned char cc; - }; - union qq pkg; - - pkg.tt.ct = 1; - pkg.tt.interlace =0; - pkg.tt.sort = 0; - pkg.tt.reserve = 0; - pkg.tt.size = resolution_-1; - - out_->write((char*)&pkg.cc,1); - } - - // *** Local Color Table *** - for (int ii=0; ii<colorTableSize_; ii++) { - out_->write((char*)&ct[ii].red,1); - out_->write((char*)&ct[ii].green,1); - out_->write((char*)&ct[ii].blue,1); - } - - // *** Image Data *** - // noCompress(); - compress(); - - // end of Image Data - unsigned char end= 0x00; - out_->write((char*)&end,1); - - // cleanup - if (pict_) - delete [] pict_; - pict_ =NULL; - pictCount_ =0; - - return TCL_OK; -} - -int TkAGIF::close(int argc, const char* argv[]) -{ - // *** Trailer *** - unsigned char end = 0x3B; - out_->write((char*)&end,1); - - out_->close(); - delete out_; - - return TCL_OK; } void TkAGIF::noCompress() diff --git a/tkagif/tkagif.h b/tkagif/tkagif.h index a2a284c..69f0264 100644 --- a/tkagif/tkagif.h +++ b/tkagif/tkagif.h @@ -28,6 +28,19 @@ #define HSIZE 5003 /* 80% occupancy */ +typedef struct { + int count; + unsigned char red; + unsigned char green; + unsigned char blue; +} Color; + +typedef struct { + unsigned char red; + unsigned char green; + unsigned char blue; +} Pixel; + class TkAGIF { private: Tcl_Interp* interp_; @@ -35,13 +48,13 @@ private: ofstream* out_; int width_; int height_; - - int colorRes_; - int colorTableSize_; int resolution_; unsigned char* pict_; long pictCount_; + + Color* colorTable_; + int colorTableSize_; long maxCode_; // Maximum code, given numBits int clearCode_; @@ -60,6 +73,9 @@ private: unsigned long currentAccumulated_; private: + void initColorTable(Color*); + void alg1(Pixel*); + void alg2(Pixel*); void noCompress(); void compress(); |