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 {
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
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
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
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
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
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
00387
00388
00389 while (counter + c_64k_ < ctrl)
00390
00391 {
00392
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
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
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
00496
00497
00498
00499
00500
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