16 #ifdef HAVE_SOFTIMAGE_PIC    27 static const float imageVersionNumber = 3.0;
    28 static const int imageCommentLength = 80;
    29 static const char imageComment[imageCommentLength+1] =
    30   "Written by pnmimage.";
    33 #define UNCOMPRESSED 0x00    34 #define MIXED_RUN_LENGTH 0x02    37 #define RGB_CHANNEL 0xe0    38 #define ALPHA_CHANNEL 0x10    41 #define SOFTIMAGE_MAGIC1 0x5380    42 #define SOFTIMAGE_MAGIC2 0xf634    44 static const char * 
const extensions_softimage[] = {
    47 static const int num_extensions_softimage = 
sizeof(extensions_softimage) / 
sizeof(
const char *);
    52 read_float(istream *file) {
    55   if (pm_readbiglong(file, &l)==0) {
    63 read_ushort_SI(istream *file) {
    65   return pm_readbigshort(file, (
short *)&x)==0 ? x : 0;
    69 read_uchar_SI(istream *file) {
    72   return (x!=EOF) ? (
unsigned char)x : 0;
    76 write_ushort_SI(ostream *file, 
unsigned short x) {
    77   pm_writebigshort(file, (
short)x);
    81 write_uchar_SI(ostream *file, 
unsigned char x) {
    86 write_float(ostream *file, 
float x) {
    87   pm_writebiglong(file, *(
long *)&x);
    91 read_channel_pkt(istream *file,
    92                  int &chained, 
int &size, 
int &type, 
int &channel) {
    93   chained = read_uchar_SI(file);
    94   size = read_uchar_SI(file);
    95   type = read_uchar_SI(file);
    96   channel = read_uchar_SI(file);
    98   if (file->eof() || file->fail()) {
   103     pnmimage_soft_cat.error()
   104       << 
"Don't know how to interpret " << size << 
" bits per pixel!\n";
   112 read_rgb(
xel *row_data, xelval *, istream *file, 
int x, 
int repeat) {
   113   xelval red, grn, blu;
   114   red = read_uchar_SI(file);
   115   grn = read_uchar_SI(file);
   116   blu = read_uchar_SI(file);
   119     PPM_ASSIGN(row_data[x], red, grn, blu);
   126 read_alpha(
xel *, xelval *alpha_data, istream *file, 
int x, 
int repeat) {
   127   xelval alpha = read_uchar_SI(file);
   130     alpha_data[x] = alpha;
   137 read_rgba(
xel *row_data, xelval *alpha_data, istream *file, 
int x, 
int repeat) {
   138   xelval red, grn, blu, alpha;
   139   red = read_uchar_SI(file);
   140   grn = read_uchar_SI(file);
   141   blu = read_uchar_SI(file);
   142   alpha = read_uchar_SI(file);
   145     PPM_ASSIGN(row_data[x], red, grn, blu);
   146     alpha_data[x] = alpha;
   154 read_scanline(
xel *row_data, xelval *alpha_data, 
int cols, istream *file,
   155               void (*read_data)(
xel *row_data, xelval *alpha_data, istream *file,
   158   if (ctype==UNCOMPRESSED) {
   159     for (
int x = 0; x<cols; x++) {
   160       read_data(row_data, alpha_data, file, x, 1);
   169       num = read_uchar_SI(file);
   178           read_data(row_data, alpha_data, file, x, 1);
   179           if (file->eof() || file->fail()) {
   188           num = read_ushort_SI(file);
   195         read_data(row_data, alpha_data, file, x, num);
   196         if (file->eof() || file->fail()) {
   210 PNMFileTypeSoftImage::
   211 PNMFileTypeSoftImage() {
   217 string PNMFileTypeSoftImage::
   226 int PNMFileTypeSoftImage::
   227 get_num_extensions()
 const {
   228   return num_extensions_softimage;
   235 string PNMFileTypeSoftImage::
   236 get_extension(
int n)
 const {
   237   nassertr(n >= 0 && n < num_extensions_softimage, 
string());
   238   return extensions_softimage[n];
   245 string PNMFileTypeSoftImage::
   246 get_suggested_extension()
 const {
   254 bool PNMFileTypeSoftImage::
   255 has_magic_number()
 const {
   264 bool PNMFileTypeSoftImage::
   265 matches_magic_number(
const string &magic_number)
 const {
   266   nassertr(magic_number.size() >= 2, 
false);
   268     ((
unsigned char)magic_number[0] << 8) |
   269     ((
unsigned char)magic_number[1]);
   270   return (mn == SOFTIMAGE_MAGIC1);
   279 make_reader(istream *file, 
bool owns_file, 
const string &magic_number) {
   281   return new Reader(
this, file, owns_file, magic_number);
   290 make_writer(ostream *file, 
bool owns_file) {
   292   return new Writer(
this, file, owns_file);
   299 PNMFileTypeSoftImage::Reader::
   300 Reader(
PNMFileType *type, istream *file, 
bool owns_file, 
string magic_number) :
   305     if (pnmimage_soft_cat.is_debug()) {
   306       pnmimage_soft_cat.debug()
   307         << 
"SoftImage image file appears to be empty.\n";
   314     ((
unsigned char)magic_number[0] << 8) |
   315     ((
unsigned char)magic_number[1]);
   317     ((
unsigned char)magic_number[2] << 8) |
   318     ((
unsigned char)magic_number[3]);
   320   if (magic1 != SOFTIMAGE_MAGIC1 || magic2 != SOFTIMAGE_MAGIC2) {
   329   _file->seekg(imageCommentLength, std::ios::cur);
   332   _file->read(pict_id, 4);
   333   if (_file->gcount() < 4) {
   338   if (memcmp(pict_id, 
"PICT", 4)!=0) {
   343   _x_size = read_ushort_SI(_file);
   344   _y_size = read_ushort_SI(_file);
   347    read_ushort_SI(_file);
   348   read_ushort_SI(_file);
   350   int chained, size, channel;
   351   if (!read_channel_pkt(_file, chained, size, rgb_ctype, channel)) {
   356   soft_color = unknown;
   358   if (channel == (RGB_CHANNEL | ALPHA_CHANNEL)) {
   362   } 
else if (channel == RGB_CHANNEL) {
   367       if (!read_channel_pkt(_file, chained, size, alpha_ctype, channel)) {
   372       if (channel == ALPHA_CHANNEL) {
   379   switch (soft_color) {
   390     pnmimage_soft_cat.error()
   391       << 
"Image is not RGB or RGBA!\n";
   397     pnmimage_soft_cat.error()
   398       << 
"Unexpected additional channels in image file.\n";
   405   if (pnmimage_soft_cat.is_debug()) {
   406     pnmimage_soft_cat.debug()
   407       << 
"Reading SoftImage " << *
this << 
"\n";
   418 bool PNMFileTypeSoftImage::Reader::
   419 supports_read_row()
 const {
   429 bool PNMFileTypeSoftImage::Reader::
   430 read_row(
xel *row_data, xelval *alpha_data, 
int x_size, 
int) {
   434   switch (soft_color) {
   436     if (!read_scanline(row_data, alpha_data, x_size, _file,
   437                        read_rgb, rgb_ctype)) {
   443     if (!read_scanline(row_data, alpha_data, x_size, _file,
   444                        read_rgba, rgb_ctype)) {
   450     if (!read_scanline(row_data, alpha_data, x_size, _file,
   451                        read_rgb, rgb_ctype)) {
   454     if (!read_scanline(row_data, alpha_data, x_size, _file,
   455                        read_alpha, alpha_ctype)) {
   469 write_channel_pkt(ostream *file,
   470                  int chained, 
int size, 
int type, 
int channel) {
   471   write_uchar_SI(file, chained);
   472   write_uchar_SI(file, size);
   473   write_uchar_SI(file, type);
   474   write_uchar_SI(file, channel);
   478 write_rgb(
xel *row_data, xelval *, ostream *file, 
int x) {
   479   write_uchar_SI(file, PPM_GETR(row_data[x]));
   480   write_uchar_SI(file, PPM_GETG(row_data[x]));
   481   write_uchar_SI(file, PPM_GETB(row_data[x]));
   485 compare_rgb(
xel *row_data, xelval *, 
int x1, 
int x2) {
   486   return PPM_EQUAL(row_data[x1], row_data[x2]);
   490 write_gray(
xel *row_data, xelval *, ostream *file, 
int x) {
   491   write_uchar_SI(file, PPM_GETB(row_data[x]));
   492   write_uchar_SI(file, PPM_GETB(row_data[x]));
   493   write_uchar_SI(file, PPM_GETB(row_data[x]));
   497 compare_gray(
xel *row_data, xelval *, 
int x1, 
int x2) {
   498   return (PPM_GETB(row_data[x1])==PPM_GETB(row_data[x2]));
   502 write_alpha(
xel *, xelval *alpha_data, ostream *file, 
int x) {
   503   write_uchar_SI(file, alpha_data[x]);
   507 compare_alpha(
xel *, xelval *alpha_data, 
int x1, 
int x2) {
   508   return (alpha_data[x1]==alpha_data[x2]);
   512 write_diff(
xel *row_data, xelval *alpha_data, ostream *file,
   513            void (*write_data)(
xel *row_data, xelval *alpha_data, ostream *file,
   515            int tox, 
int length) {
   517     nassertv(length<=128);
   519     write_uchar_SI(file, length-1);
   522       write_data(row_data, alpha_data, file, tox-length);
   528 write_same(
xel *row_data, xelval *alpha_data, ostream *file,
   529            void (*write_data)(
xel *row_data, xelval *alpha_data, ostream *file,
   531            int tox, 
int length) {
   533     write_diff(row_data, alpha_data, file, write_data, tox, length);
   535   } 
else if (length>0) {
   537       write_uchar_SI(file, length+127);
   539       write_uchar_SI(file, 128);
   540       write_ushort_SI(file, length);
   542     write_data(row_data, alpha_data, file, tox);
   548 write_scanline(
xel *row_data, xelval *alpha_data, 
int cols, ostream *file,
   549                int (*compare_data)(
xel *row_data, xelval *alpha_data,
   551                void (*write_data)(
xel *row_data, xelval *alpha_data,
   552                                   ostream *file, 
int x)) {
   567       if (!compare_data(row_data, alpha_data, x, x-run_length)) {
   570         if (run_length <= 1) {
   581           write_same(row_data, alpha_data, file, write_data, x-1, run_length);
   592       if (run_length>128) {
   596         int excess = run_length - 128;
   597         write_diff(row_data, alpha_data, file, write_data, x-excess-1, 128);
   600       } 
else if (run_length > 2 &&
   601                  compare_data(row_data, alpha_data, x, x-1) &&
   602                  compare_data(row_data, alpha_data, x, x-2)) {
   607         write_diff(row_data, alpha_data, file, write_data, x-3, run_length-2);
   621       write_same(row_data, alpha_data, file, write_data, cols-1, run_length);
   625       if (run_length>128) {
   626         int excess = run_length - 128;
   627         write_diff(row_data, alpha_data, file, write_data, cols-excess-1, 128);
   631       write_diff(row_data, alpha_data, file, write_data, cols-1, run_length);
   639 PNMFileTypeSoftImage::Writer::
   640 Writer(
PNMFileType *type, ostream *file, 
bool owns_file) :
   651 bool PNMFileTypeSoftImage::Writer::
   652 supports_write_row()
 const {
   666 bool PNMFileTypeSoftImage::Writer::
   668   write_ushort_SI(_file, SOFTIMAGE_MAGIC1);
   669   write_ushort_SI(_file, SOFTIMAGE_MAGIC2);
   670   write_float(_file, imageVersionNumber);
   672   _file->write(imageComment, imageCommentLength);
   673   _file->write(
"PICT", 4);
   675   write_ushort_SI(_file, _x_size);
   676   write_ushort_SI(_file, _y_size);
   678   write_float(_file, 1.0);    
   679   write_ushort_SI(_file, 3);     
   680   write_ushort_SI(_file, 0);     
   686     write_channel_pkt(_file, 1, 8, MIXED_RUN_LENGTH, RGB_CHANNEL);
   687     write_channel_pkt(_file, 0, 8, MIXED_RUN_LENGTH, ALPHA_CHANNEL);
   689     write_channel_pkt(_file, 0, 8, MIXED_RUN_LENGTH, RGB_CHANNEL);
   706 bool PNMFileTypeSoftImage::Writer::
   707 write_row(
xel *row_data, xelval *alpha_data) {
   708   if (is_grayscale()) {
   709     write_scanline(row_data, alpha_data, _x_size, _file, compare_gray, write_gray);
   712     write_scanline(row_data, alpha_data, _x_size, _file, compare_rgb, write_rgb);
   716     write_scanline(row_data, alpha_data, _x_size, _file, compare_alpha, write_alpha);
   719   return !_file->fail();
   727 void PNMFileTypeSoftImage::
   728 register_with_read_factory() {
   730     register_factory(get_class_type(), make_PNMFileTypeSoftImage);
   746 #endif  // HAVE_SOFTIMAGE_PIC PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Base class for objects that can be written to and read from Bam files.
 
This is the base class of a family of classes that represent particular image file types that PNMImag...
 
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
An instance of this class is passed to the Factory when requesting it to do its business and construc...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PNMFileType * get_type_by_handle(TypeHandle handle) const
Returns the PNMFileType instance stored in the registry for the given TypeHandle, e....
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is an abstract base class that defines the interface for reading image files of various types.
 
This is an abstract base class that defines the interface for writing image files of various types.
 
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
 
TypeHandle is the identifier used to differentiate C++ class types.