Nbrevu

Tuenti Contest 14 (Pablo Moreno)

Jun 20th, 2011
978
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Author: Pablo Moreno Olalla
  3.     Email address: darthbrevu@yahoo.es
  4. */
  5. #include <cstdio>
  6. #include <string>
  7. #include <sstream>
  8. #include <iostream>
  9. #include <stdint.h>
  10. #include <stdexcept>
  11.  
  12. using namespace std;
  13.  
  14. //This code is a little too ad hoc, which means that you shouldn't use it for general BMP files!
  15. class Bmp24bits {
  16. private:
  17.     uint32_t width;
  18.     uint32_t height;
  19.     unsigned char **r;
  20.     unsigned char **g;
  21.     unsigned char **b;
  22. public:
  23.     Bmp24bits(const char *fn)   {
  24.         uint32_t ptr;
  25.         FILE *fd=fopen(fn,"rb");
  26.         if (!fd) throw runtime_error("Couldn't open file.");
  27.         fseek(fd,10,SEEK_SET);
  28.         fread(static_cast<void *>(&ptr),4,1,fd);
  29.         fseek(fd,4,SEEK_CUR);
  30.         // Reading both width and height seems like a good trick, but may be unsafe due to alignment issues.
  31.         // It would work on most computers, though.
  32.         fread(static_cast<void *>(&width),4,1,fd);
  33.         fread(static_cast<void *>(&height),4,1,fd);
  34.         r=new unsigned char *[height];
  35.         g=new unsigned char *[height];
  36.         b=new unsigned char *[height];
  37.         fseek(fd,ptr,SEEK_SET);
  38.         unsigned char *tmpbuf=new unsigned char[3*width];
  39.         for (int i=height-1;i>=0;--i)   {
  40.             r[i]=new unsigned char[width];
  41.             g[i]=new unsigned char[width];
  42.             b[i]=new unsigned char[width];
  43.             unsigned char *rt=r[i];
  44.             unsigned char *gt=g[i];
  45.             unsigned char *bt=b[i];
  46.             fread(static_cast<void *>(tmpbuf),1,3*width,fd);
  47.             unsigned char *p=tmpbuf;
  48.             for (size_t j=0;j<width;++j)    {
  49.                 bt[j]=p[0];
  50.                 gt[j]=p[1];
  51.                 rt[j]=p[2];
  52.                 p+=3;
  53.             }
  54.         }
  55.         delete[] tmpbuf;
  56.         fclose(fd);
  57.     }
  58.     ~Bmp24bits()    {
  59.         for (size_t i=0;i<height;++i)   {
  60.             delete[] r[i];
  61.             delete[] g[i];
  62.             delete[] b[i];
  63.         }
  64.         delete[] r;
  65.         delete[] g;
  66.         delete[] b;
  67.     }
  68.     inline unsigned int computeSum(char component,size_t row) const {
  69.         if (row>height) return 0;
  70.         const unsigned char *p;
  71.         if (component=='r'||component=='R') p=r[row];
  72.         else if (component=='g'||component=='G') p=g[row];
  73.         else if (component=='b'||component=='B') p=b[row];
  74.         else return 0;
  75.         unsigned int res=1; //It seems that I must do this (instead of res=0), but I don't understand why :(.
  76.         for (size_t i=0;i<width;++i) res+=static_cast<unsigned int>(p[i]);
  77.         return res;
  78.     }
  79.     inline uint32_t getWidth() const    {
  80.         return width;
  81.     }
  82.     inline uint32_t getHeight() const   {
  83.         return height;
  84.     }
  85. };
  86.  
  87. int main(int argc,char **argv)  {
  88.     const char *fn;
  89.     fn=((argc<=1)?"trabaja.bmp":argv[1]);
  90.     //The following two lines are not strictly necessary, but make the code a little more handy.
  91.     if (argc>=3) freopen(argv[2],"r",stdin);
  92.     if (argc>=4) freopen(argv[3],"w",stdout);
  93.     Bmp24bits bm(fn);
  94.     string tmp;
  95.     char c;
  96.     unsigned int line;
  97.     do  {
  98.         getline(cin,tmp);
  99.         if (sscanf(tmp.c_str(),"%c%u",&c,&line)!=2) break;
  100.         else cout<<bm.computeSum(c,line)<<endl;
  101.     }   while (!cin.eof());
  102.     return 0;   //bm will be deleted and freed automatically, so no need to do it explicitly :).
  103. }
RAW Paste Data