Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vuPPMReader.cpp

Go to the documentation of this file.
00001 #include "vuPPMReader.h"
00002 
00003 vuPPM::vuPPM ()
00004 
00005 {
00006         fp = NULL;
00007         m_buf = NULL;
00008         m_buf_size = 0;
00009 }
00010 
00011 vuPPM::~vuPPM ()
00012 
00013 {
00014         if (m_buf != NULL)
00015                 delete [] m_buf;
00016 }
00017 
00018 bool vuPPM::SaveCompressedImage (char* fname, vuImage &img)
00019 
00020 {
00021         img.get_extents (m_x, m_y);
00022 
00023         m_z = CompressToBuffer (img);
00024 
00025         fp = fopen (fname, "w");
00026 
00027         WriteCompressedHeader (img);
00028         
00029         return true;
00030 }
00031 
00032 bool vuPPM::WriteCompressedHeader (vuImage &img)
00033 
00034 {
00035         fputs ("C1 ", fp);
00036 
00037         char tstring [6];
00038         char tstring2 [6];
00039 
00040         gcvt (m_x, 4, tstring);
00041 
00042         int i = 0;
00043         int j = 0;
00044 
00045         while (i < (int (4 - strlen (tstring))))
00046 
00047         {
00048                 tstring2 [j] = '0';
00049                 i++;
00050                 j++;
00051         }
00052 
00053         strcpy (&(tstring2 [j]), tstring);
00054 
00055         fputs (tstring2, fp);
00056         fputc (' ', fp);
00057 
00058         gcvt (m_y, 4, tstring);
00059 
00060         i = 0;
00061         j = 0;
00062 
00063         while (i < (int (4 - strlen (tstring))))
00064 
00065         {
00066                 tstring2 [j] = '0';
00067                 i++;
00068                 j++;
00069         }
00070 
00071         strcpy (&(tstring2 [j]), tstring);
00072 
00073         fputs (tstring2, fp);
00074         fputc (' ', fp);
00075 
00076         int t1 = m_z;
00077 
00078         unsigned char tstr [5];
00079 
00080         tstr [4] = '\0';
00081 
00082         tstr [3] = t1 % 256;
00083         t1 /= 256;
00084 
00085         tstr [2] = t1 % 256;
00086         t1 /= 256;
00087 
00088         tstr [1] = t1 % 256;
00089         t1 /= 256;
00090 
00091         tstr [0] = t1 % 256;
00092         t1 /= 256;
00093 
00094         fputc (tstr [0], fp);
00095         fputc (tstr [1], fp);
00096         fputc (tstr [2], fp);
00097         fputc (tstr [3], fp);
00098         
00099         return true;
00100 }
00101 
00102 int vuPPM::CompressToBuffer (vuImage &img)
00103 
00104 {
00105         if (m_x * m_y * 3 > m_buf_size)
00106 
00107         {
00108                 delete [] m_buf;
00109 
00110                 m_buf = new unsigned char [m_x * m_y * 3];
00111 
00112                 m_buf_size = m_x * m_y * 3;
00113         }
00114 
00115         m_z = 0;
00116 
00117         int counter = 0;
00118         int m_buf_pos = 0;
00119 
00120         char *rgb = (char *) (img.get_rgb ());
00121 
00122         while (counter < m_x * m_y * 3)
00123 
00124         {
00125                 int runlength = 0;
00126 
00127                 if ((rgb [counter] == rgb [counter + 3]) && (rgb [counter + 1] == rgb [counter + 4]) && (rgb [counter + 2] == rgb [counter + 5]))
00128 
00129                 {
00130                         while ((runlength < 256) && (rgb [counter] == rgb [counter + 3]) && (rgb [counter + 1] == rgb [counter + 4]) && (rgb [counter + 2] == rgb [counter + 5]))
00131 
00132                         {
00133                                 counter += 3;
00134 
00135                                 runlength++;
00136                         }
00137 
00138                         m_buf [m_buf_pos++] = 0;
00139                         m_buf [m_buf_pos++] = runlength;
00140 
00141                         m_buf [m_buf_pos++] = rgb [counter];
00142                         m_buf [m_buf_pos++] = rgb [counter + 1];
00143                         m_buf [m_buf_pos++] = rgb [counter + 2];
00144                 }
00145 
00146                 else
00147 
00148                 {
00149                         if (rgb [counter] == 0)
00150                                 m_buf [m_buf_pos++] = 1;
00151                         else
00152                                 m_buf [m_buf_pos++] = rgb [counter];
00153 
00154                         m_buf [m_buf_pos++] = rgb [counter + 1];
00155                         m_buf [m_buf_pos++] = rgb [counter + 2];
00156                 }
00157 
00158                 counter += 3;
00159         }
00160 
00161         return m_buf_pos;
00162 }
00163 
00164 bool vuPPM::SaveImage (char* fname, vuImage &img)
00165 
00166 {       // the commented code will read any valid ppm header,
00167         // the uncommented code is faster, and will read those saved
00168         // by this class
00169 /*      fp = fopen (fname, "w");
00170 
00171         if (fp == NULL)
00172                 return false;
00173 
00174         char tnum [20];
00175 
00176         fputs ("P6\n", fp);
00177 
00178         img.get_extents (m_x, m_y);
00179 
00180         gcvt (double (m_x), 16, tnum);
00181         strcat (tnum, "\n");
00182 
00183         fputs (tnum, fp);
00184 
00185         gcvt (double (m_y), 16, tnum);
00186         strcat (tnum, "\n");
00187 
00188         fputs (tnum, fp);
00189 
00190         gcvt (255.0, 16, tnum);
00191         strcat (tnum, "\n");
00192 
00193         fputs (tnum, fp); */
00194 
00195         img.get_extents (m_x, m_y);
00196 
00197         fp = fopen (fname, "w");
00198 
00199         WriteHeader (img);
00200 
00201         unsigned char* tchar = (unsigned char*) (img.get_rgb ());
00202 
00203 //      fwrite (tchar, 1, 3 * m_x * m_y, fp);
00204 
00205         for (int i = 0; i < 3 * m_x * m_y; i++)
00206                 fputc (int (tchar [i]), fp);
00207 
00208         fclose (fp);
00209 
00210         return true;
00211 }
00212 
00213 const int c_64k_ = 16 * 16 * 16 * 16;
00214 
00215 #include <errno.h>
00216 
00217 bool vuPPM::ReadCompressedImage (char* fname, vuImage &img, int readtype)
00218 
00219 {
00220         if (m_buf_size < m_z)
00221 
00222         {
00223                 if (m_buf)
00224                         delete [] m_buf;
00225 
00226                 m_buf = new unsigned char [m_z];
00227         }
00228 
00229         int x,y;
00230 
00231         img.get_extents (x, y);
00232 
00233         if ((x != m_x) || (y != m_y))
00234                 if (!img.init (m_x, m_y))
00235 
00236                 {
00237                         cout << "couldn't allocate the memory needed" << endl;
00238 
00239                         return false;
00240                 }
00241 
00242         char* rgb = (char*) (img.get_rgb ());
00243 
00244         int ctrl = m_z;
00245 
00246 //      read (&(rgb [counter]), 1, ctrl, fp);
00247 
00248         int j = 0;
00249         int runlength;
00250 
00251         int r, g, b;
00252 
00253         int i = 0;
00254 
00255         while (int (counter + c_64k_) < ctrl)
00256 
00257         {
00258 //              fread_unlocked (&(rgb [counter]), 1, c_64k_, fp);
00259                 fread (&(m_buf [counter]), 1, c_64k_, fp);
00260 
00261                 while (i < int (counter + c_64k_ - 6))
00262 
00263                 {
00264                         if (m_buf [i] == 0)
00265 
00266                         {
00267                                 runlength = m_buf [++i];
00268 
00269                                 r = m_buf [++i];
00270                                 g = m_buf [++i];
00271                                 b = m_buf [i];
00272 
00273                                 while (runlength > 0)
00274 
00275                                 {
00276                                         rgb [j++] = r;
00277                                         rgb [j++] = g;
00278                                         rgb [j++] = b;
00279 
00280                                         runlength--;
00281                                 }
00282                         }
00283 
00284                         else
00285 
00286                         {
00287                                 rgb [j++] = m_buf [i++];
00288                                 rgb [j++] = m_buf [i++];
00289                                 rgb [j++] = m_buf [i];
00290                         }
00291 
00292                         i++;
00293                 }
00294 
00295                 counter += c_64k_;
00296         }
00297 
00298         fread (&(m_buf [counter]), 1, ctrl - counter, fp);
00299 
00300         while (i < ctrl)
00301 
00302         {
00303                 if (m_buf [i] == 0)
00304 
00305                 {
00306                         runlength = m_buf [++i];
00307 
00308                         r = m_buf [++i];
00309                         g = m_buf [++i];
00310                         b = m_buf [i];
00311 
00312                         while (runlength > 0)
00313 
00314                         {
00315                                 rgb [j++] = r;
00316                                 rgb [j++] = g;
00317                                 rgb [j++] = b;
00318 
00319                                 runlength--;
00320                         }
00321                 }
00322 
00323                 else
00324 
00325                 {
00326                         rgb [j++] = m_buf [i++];
00327                         rgb [j++] = m_buf [i++];
00328                         rgb [j++] = m_buf [i];
00329                 }
00330 
00331                 i++;
00332         }
00333 
00334         fclose (fp);
00335 
00336         return true;
00337 }
00338 
00339 bool vuPPM::ReadImage (char* fname, vuImage &img, int readtype)
00340 
00341 {
00342         fp = fopen (fname, "r");
00343 
00344         if (fp == NULL)
00345 
00346         {
00347                 cout << "couldn't open: " << fname << endl;
00348                 cout << strerror (errno) << endl;
00349                 return false;
00350         }
00351 
00352         int readval = ReadHeader (img, readtype);
00353 
00354         if (!readval)
00355 
00356         {
00357                 cout << "couldn't read the header for; " << fname << endl;
00358                 return false;
00359         }
00360 
00361         if (readval == 2)
00362                 return ReadCompressedImage (fname, img, readtype);
00363 
00364 //      char rgb [c_64k_];
00365         char* rgb;
00366 
00367         int counter = 0;
00368 
00369         int x,y;
00370 
00371         img.get_extents (x, y);
00372 
00373         if ((x != m_x) || (y != m_y))
00374                 if (!img.init (m_x, m_y))
00375 
00376                 {
00377                         cout << "couldn't allocate the memory needed" << endl;
00378 
00379                         return false;
00380                 }
00381 
00382         rgb = (char*) (img.get_rgb ());
00383 
00384         int ctrl = 3 * m_x * m_y;
00385 
00386 //      read (&(rgb [counter]), 1, ctrl, fp);
00387 
00388 
00389         while (counter + c_64k_ < ctrl)
00390 
00391         {
00392 //              fread_unlocked (&(rgb [counter]), 1, c_64k_, fp);
00393                 fread (&(rgb [counter]), 1, c_64k_, fp);
00394 
00395                 counter += c_64k_;
00396         }
00397 
00398         fread (&(rgb [counter]), 1, ctrl - counter, fp);
00399 
00400         fclose (fp);
00401 
00402 //      cout << "read took: " << twatch.Time () << endl;
00403 
00404 //      char rgb [3 * m_x * m_y + 2];
00405 
00406                 // over 60 ms faster to use this than
00407                 // for do fread (3 bytes)
00408 
00409 /*      img.init (m_x, m_y);
00410 
00411         cout << "s1" << endl;
00412 
00413         fread ((void*) (img.get_rgb ()), 1, 3 * m_x * m_y, fp);
00414 
00415         cout << "s2" << endl;
00416 
00417         fclose (fp);*/
00418 
00419         return true;
00420 }
00421 
00422 bool vuPPM::ReadImageFromBuffer (char* buf, vuImage &img, int readtype)
00423 
00424 {
00425         if (!ReadHeader (img, buf, readtype))
00426 
00427         {
00428                 cout << "couldn't read the header for this buffer " << endl;
00429                 return false;
00430         }
00431 
00432         int x,y;
00433 
00434         img.get_extents (x, y);
00435 
00436         if ((x != m_x) || (y != m_y))
00437                 if (!img.init (m_x, m_y))
00438 
00439                 {
00440                         cout << "couldn't allocate the memory needed" << endl;
00441 
00442                         return false;
00443                 }
00444 
00445         img.set_data ((byte *) (&(buf [18])));
00446 
00447         return true;
00448 }
00449 
00450 bool vuPPM::SaveImage (char* fname)
00451 
00452 {
00453         return false;
00454 }
00455 
00456 bool vuPPM::ReadImage (char* fname)
00457 
00458 {
00459         return false;
00460 }
00461 
00462 bool vuPPM::OpenImage (char* fname, vuImage &img)
00463 
00464 {
00465         fp = fopen (fname, "r");
00466 
00467         if (fp == NULL)
00468 
00469         {
00470                 cout << "couldn't open: " << fname << endl;
00471                 return false;
00472         }
00473 
00474 
00475         if (!ReadHeader (img))
00476 
00477         {
00478                 cout << "couldn't read the header for; " << fname << endl;
00479                 return false;
00480         }
00481 
00482         img.init (m_x, m_y);
00483 
00484         counter = 0;
00485 
00486         return true;
00487 }
00488 
00489 
00490 unsigned int vuPPM::Readnext64KB (vuImage &img)
00491 
00492 {
00493         char rgb [c_64k_];
00494 
00495                 // over 60 ms faster to use this than
00496                 // for do fread (3 bytes)
00497         //fread (rgb, _64k_);
00498 
00499                 // 4 ms faster to use this than
00500                 // the for do { for do {...} } loops.
00501         img.set_rgb ((byte*) (rgb));
00502 
00503         fclose (fp);
00504 
00505         return 0;
00506 }
00507 
00508 bool vuPPM::CloseImage ()
00509 
00510 {
00511         return false;
00512 }
00513 
00514 bool vuPPM::set_xy (int x, int y)
00515 
00516 {
00517         m_x = x;
00518         m_y = y;
00519 
00520         return m_Image.init (x, y);
00521 }
00522 
00523 int vuPPM::get_x ()
00524 
00525 {
00526         return m_x;
00527 }
00528 
00529 int vuPPM::get_y ()
00530 
00531 {
00532         return m_y;
00533 }
00534 
00535 inline bool IsSpace (char temp)
00536 
00537 {
00538         return ((temp == ' ') || (temp == '\t') || (temp == '\n'));
00539 }
00540 
00541 inline bool IsNumber (char temp)
00542 
00543 {
00544         return ((temp >= '0') && (temp <= '9'));
00545 }
00546 
00547 inline bool IsNotNext (char temp)
00548 
00549 {
00550         return ((IsSpace (temp)) || (!IsNumber (temp)));
00551 }
00552 
00553 bool vuPPM::WriteHeader (vuImage &img)
00554 
00555 {
00556         char tstring [10];
00557         char tstring2 [10];
00558 
00559         gcvt (m_x, 4, tstring);
00560 
00561         if (strlen (tstring) > 3)
00562                 return false;
00563 
00564         while (strlen (tstring) < 4)
00565 
00566         {
00567                 strcpy (tstring2, "0");
00568 
00569                 strcat (tstring2, tstring);
00570                 strcpy (tstring, tstring2);
00571         }
00572 
00573         fputs ("P6 ", fp);
00574         fputs (tstring, fp);
00575         fputs (" ", fp);
00576 
00577         gcvt (m_y, 4, tstring);
00578 
00579         if (strlen (tstring) > 3)
00580                 return false;
00581 
00582         while (strlen (tstring) < 4)
00583 
00584         {
00585                 strcpy (tstring2, "0");
00586 
00587                 strcat (tstring2, tstring);
00588                 strcpy (tstring, tstring2);
00589         }
00590 
00591         fputs (tstring, fp);
00592         fputs (" 0255\n", fp);
00593 
00594         return true;
00595 }
00596 
00597 int vuPPM::ReadHeader (vuImage &img, char* buf, int readtype)
00598 
00599 {
00600         int retval;
00601 
00602         if (readtype == 1)
00603 
00604         {
00605                 retval = 1;
00606 
00607                 if (strncmp ("P6 ", buf, 3))
00608 
00609                 {
00610                         retval = 2;
00611 
00612                         if (strncmp ("C1 ", buf, 3))
00613                                 return 0;
00614                 }
00615 
00616                 unsigned char * ubuf = (unsigned char *) (buf);
00617 
00618                 m_x = atoi (&(buf [3]));
00619                 m_y = atoi (&(buf [8]));
00620                 m_z = ((ubuf [13] * 256 + ubuf [14]) * 256 + ubuf [15]) * 256 + ubuf [16];
00621 
00622                 return retval;
00623         }
00624 
00625         if (readtype == 0)
00626 
00627         {
00628                 int counter = 0;
00629 
00630                 while ((buf [counter] != 'P') && (buf [counter] != '\0'))
00631                         counter++;
00632 
00633                 if (buf [counter] == '\0')
00634                         return false;
00635 
00636                 if (buf [++counter] != '6')
00637 
00638                 {
00639                         cout << "not p6" << endl;
00640                         return false;
00641                 }
00642 
00643                 counter++;
00644 
00645                 while ((buf [counter] != '\0') && (IsNotNext (buf [counter])))
00646                         counter++;
00647 
00648                 while (buf [counter] == '\0')
00649 
00650                 {
00651                         if (buf [counter] == EOF)
00652                                 return false;
00653 
00654                         while ((buf [counter] != '\0') && (IsNotNext (buf [counter])))
00655                                 counter++;
00656                 }
00657 
00658                 m_x = atoi (&(buf [counter]));
00659 
00660                 while ((buf [counter] != '\0') && (IsNumber (buf [counter])))
00661                         counter++;
00662 
00663                 while ((buf [counter] != '\0') && (IsNotNext (--buf [counter])))
00664                         counter++;
00665 
00666                 while (buf [counter] == '\0')
00667 
00668                 {
00669                         if (buf [counter] == EOF)
00670                                 return false;
00671 
00672                         while ((buf [counter] != '\0') && (IsNotNext (buf [counter])))
00673                                 counter++;
00674                 }
00675 
00676                 m_y = atoi (&(buf [counter]));
00677 
00678                 while ((buf [counter] != '\0') && (IsNumber (buf [counter])))
00679                         counter++;
00680 
00681                 while ((buf [counter] != '\0') && (IsNotNext (buf [counter])))
00682                         counter++;
00683 
00684                 while (buf [counter] == '\0')
00685 
00686                 {
00687                         if (buf [counter] == EOF)
00688                                 return false;
00689 
00690                         while ((buf [counter] != '\0') && (IsNotNext (buf [counter])))
00691                                 counter++;
00692                 }
00693 
00694                 return true;
00695         }
00696 
00697         cout << "Error: readtype not handled" << endl
00698                 << "readtype = " << readtype << endl;
00699 
00700         return false;
00701 }
00702 
00703 int vuPPM::ReadHeader (vuImage &img, int readtype)
00704 
00705 {
00706         int retval;
00707 
00708         if (readtype == 1)
00709 
00710         {
00711                 char c_buf [20];
00712 
00713                 fread (c_buf, 1, 18, fp);
00714 
00715                 retval = 1;
00716 
00717                 if (strncmp ("P6 ", c_buf, 3))
00718 
00719                 {
00720                         if (strncmp ("C1 ", c_buf, 3))
00721                                 return 0;
00722 
00723                         retval = 2;
00724                 }
00725 
00726                 unsigned char * ubuf = (unsigned char *) (c_buf);
00727 
00728                 m_x = atoi ((char *) (&(ubuf [3])));
00729                 m_y = atoi ((char *) (&(ubuf [8])));
00730                 m_z = ((ubuf [13] * 256 + ubuf [14]) * 256 + ubuf [15]) * 256 + ubuf [16];
00731 
00732                 return retval;
00733         }
00734 
00735         if (readtype == 0)
00736 
00737         {
00738                 char c_buf [126];
00739 
00740                 fgets (c_buf, 125, fp);
00741 
00742                 int counter = 0;
00743 
00744                 while (c_buf [counter] != 'P')
00745 
00746                 {
00747                         if (c_buf [counter] == '\n')
00748 
00749                         {
00750                                 fgets (c_buf, 125, fp);
00751 
00752                                 counter = -1;
00753 
00754                                 if (c_buf [counter] == '\0')
00755                                         return false;
00756                         }
00757 
00758                         counter++;
00759                 }
00760 
00761                 if (c_buf [++counter] != '6')
00762 
00763                 {
00764                         cout << "not p6" << endl;
00765                         return false;
00766                 }
00767 
00768                 counter++;
00769 
00770                 while ((c_buf [counter] != '\0') && (IsNotNext (c_buf [counter])))
00771                         counter++;
00772 
00773                 while (c_buf [counter] == '\0')
00774 
00775                 {
00776                         fgets (c_buf, 125, fp);
00777                         counter = 0;
00778 
00779                         if (c_buf [0] == EOF)
00780                                 return false;
00781 
00782                         while ((c_buf [counter] != '\0') && (IsNotNext (c_buf [counter])))
00783                                 counter++;
00784                 }
00785 
00786                 m_x = atoi (&(c_buf [counter]));
00787 
00788                 while ((c_buf [counter] != '\0') && (IsNumber (c_buf [counter])))
00789                         counter++;
00790 
00791                 while ((c_buf [counter] != '\0') && (IsNotNext (c_buf [counter])))
00792                         counter++;
00793 
00794                 while (c_buf [counter] == '\0')
00795 
00796                 {
00797                         fgets (c_buf, 125, fp);
00798                         counter = 0;
00799 
00800                         if (c_buf [0] == EOF)
00801                                 return false;
00802 
00803                         while ((c_buf [counter] != '\0') && (IsNotNext (c_buf [counter])))
00804                                 counter++;
00805                 }
00806 
00807                 m_y = atoi (&(c_buf [counter]));
00808 
00809                 while ((c_buf [counter] != '\0') && (IsNumber (c_buf [counter])))
00810                         counter++;
00811 
00812                 while ((c_buf [counter] != '\0') && (IsNotNext (c_buf [counter])))
00813                         counter++;
00814 
00815                 while (c_buf [counter] == '\0')
00816 
00817                 {
00818                         fgets (c_buf, 125, fp);
00819                         counter = 0;
00820 
00821                         if (c_buf [0] == EOF)
00822                                 return false;
00823 
00824                         while ((c_buf [counter] != '\0') && (IsNotNext (c_buf [counter])))
00825                                 counter++;
00826                 }
00827 
00828                 return true;
00829         }
00830 
00831         cout << "Error: readtype not handled" << endl
00832                 << "readtype = " << readtype << endl;
00833 
00834         return false;
00835 }
00836 
00837 
00838 

Generated on Wed Dec 15 21:20:35 2004 for vuVolume by  doxygen 1.3.9.1