ditherer.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:5k
源码类别:

DVD

开发平台:

Unix_Linux

  1. #include <iostream>
  2. #include "ditherer.hh"
  3. map<string,Ditherer * (*)()> Ditherer::ditherStore;
  4. int Ditherer::addModule(class Ditherer * (*alloc)(),string name) {
  5.    Ditherer::ditherStore[name]=alloc;
  6. }
  7. Ditherer * Ditherer::allocModule(string name) {
  8.    map<string,Ditherer * (*)()>::iterator store_it;
  9.    if (ditherStore.empty()) {
  10.       Ditherer::loadDefaultModules();
  11.    }
  12.    store_it=ditherStore.find(name);
  13.    if (store_it != ditherStore.end()) {
  14.       return ((store_it->second))();
  15.    } else {
  16.       return 0;
  17.    }
  18. }
  19. string Ditherer::getRegisteredModules() {
  20.    if (ditherStore.empty()) {
  21.       Ditherer::loadDefaultModules();
  22.    }
  23.    
  24. }
  25. void Ditherer::setBpp(int bpp) {
  26.    if (!_bpp) {
  27.       _bpp=bpp;
  28.       if (!_pixelSize) {_pixelSize=bpp/8+((bpp%8 != 0)?1:0);}
  29.    } else {
  30.       if (bpp!=_bpp) {
  31.          cerr<<"Ditherer::setBpp() can't be called if _bpp is already set"
  32.              << endl;
  33.          exit(1);
  34.       }
  35.    }
  36. }
  37. void Ditherer::setPixelSize(int pixelSize) {
  38.    if (_pixelSize == 0 || pixelSize == _pixelSize) {
  39.       _pixelSize=pixelSize;
  40.    } else {
  41.       cerr<<"Ditherer::setPixelSize() can't be called if _pixelSize is already set"
  42.           << endl;
  43.       exit(1);
  44.    }
  45. }
  46. GenericDitherer::GenericDitherer() {
  47.    tempory_Y=(unsigned char*)0;
  48.    tempory_Cr=(unsigned char*)0;
  49.    tempory_Cb=(unsigned char*)0;
  50. }
  51. GenericDitherer::~GenericDitherer() {
  52.    delete tempory_Y;
  53.    delete tempory_Cr;
  54.    delete tempory_Cb;
  55. }
  56. void GenericDitherer::resizeYandDither(unsigned char * tY,
  57.                                        unsigned char * tCr,
  58.                                        unsigned char * tCb,
  59.                                        unsigned char * dithered_img,
  60.                                        int origXsize,int origYsize,
  61.                                        int newYsize,int screenWidth) {
  62.    int nb_skip=origYsize-newYsize+1;
  63.    int skipped;
  64.    int block_height;
  65.    
  66.    for (skipped=0;skipped<nb_skip;++skipped) {
  67.       block_height=(skipped+1)*origYsize/nb_skip-(skipped)*origYsize/nb_skip;
  68.       ditherBlock(tY,tCr,tCb,
  69.                   dithered_img,
  70.                   origXsize,block_height-1,screenWidth);
  71.       tY+=block_height*origXsize;
  72.       tCr+=block_height/2*origXsize/2;
  73.       tCb+=block_height/2*origXsize/2;
  74.       dithered_img+=(block_height-1)*origXsize*_pixelSize;
  75.    }
  76. }
  77. void GenericDitherer::changeSize(unsigned char * orig,unsigned char * dst,
  78.                                  int origXsize,int origYsize,
  79.                                  int newXsize, int newYsize) {
  80.    int k,l=0;
  81.    int ll;
  82.    
  83.    for(l=0;l<newYsize;l++) {
  84.       ll=(l*origYsize/newYsize)*origXsize;
  85.       if (origXsize==newXsize) {
  86.          /* just a vertical aspect ratio change) */
  87.          memcpy(dst,orig+ll,origXsize);
  88.          dst+=origXsize;
  89.       } else {
  90.          for(k=0;k<newXsize;++k) {
  91.             *(dst++)=orig[ll+(k*origXsize/newXsize)];
  92.          }
  93.       }
  94.    }
  95. }
  96. void  GenericDitherer::checking() {
  97.    if (_pixelSize==0) {
  98.       cerr<<"method GenericDitherer::setBpp() or GenericDitherer:setPixelSize() must be called before dithering"
  99.           <<endl;
  100.       exit(1);
  101.    }
  102. }
  103. void GenericDitherer::dither(unsigned char * tY,
  104.                              unsigned char * tCr,
  105.                              unsigned char * tCb,
  106.                              unsigned char * dithered_img,
  107.                              int imgWidth,
  108.                              int imgHeight,
  109.                              int viewWidth,
  110.                              int viewHeight,
  111.                              int screenWidth) {
  112.    checking();
  113.    if (tempory_Y==0) {
  114.       tempory_Y=new unsigned char[viewWidth*viewWidth];
  115.       tempory_Cr=new unsigned char[viewWidth/2*viewWidth/2];
  116.       tempory_Cb=new unsigned char[viewWidth/2*viewWidth/2];
  117.    }
  118.    
  119.    if (imgWidth!=viewWidth
  120.        || imgHeight!= viewHeight) {
  121.       if ((imgWidth==viewWidth)
  122.           && (imgHeight>viewHeight)
  123.           && (viewHeight>(imgHeight/2))) {
  124.          resizeYandDither(tY,tCr,tCb,
  125.                           dithered_img,
  126.                           imgWidth,imgHeight,viewHeight,screenWidth);
  127.       } else {
  128.          /* full resize needed */
  129.          changeSize(tY,tempory_Y,imgWidth,imgHeight,viewWidth,viewHeight);
  130.          changeSize(tCr,tempory_Cr,imgWidth/2,imgHeight/2,viewWidth/2,viewHeight/2);
  131.          changeSize(tCb,tempory_Cb,imgWidth/2,imgHeight/2,viewWidth/2,viewHeight/2);
  132.          ditherBlock(tempory_Y,tempory_Cr,tempory_Cb,
  133.                      dithered_img,
  134.                      viewWidth,viewHeight,screenWidth);
  135.       }
  136.    } else {
  137.       ditherBlock(tY,tCr,tCb,
  138.                   dithered_img,
  139.                   viewWidth,viewHeight,screenWidth);
  140.    }
  141. }