image_util.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:9k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: image_util.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:41:49  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: image_util.cpp,v 1000.2 2004/06/01 19:41:49 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <util/image/image_util.hpp>
  41. #include <util/image/image_exception.hpp>
  42. #include <corelib/ncbi_limits.hpp>
  43. BEGIN_NCBI_SCOPE
  44. CImage* CImageUtil::Scale(const CImage& image, size_t width, size_t height,
  45.                           EScale scale)
  46. {
  47.     CRef<CImage> new_image(new CImage(width, height, image.GetDepth()));
  48.     float w_step = (float)(image.GetWidth())  / (float)(width);
  49.     float h_step = (float)(image.GetHeight()) / (float)(height);
  50.     _TRACE("scale: "
  51.            << image.GetWidth() << "x" << image.GetHeight() << " -> "
  52.            << width << "x" << height);
  53.     float h_offs = 0;
  54.     for (size_t i = 0;  i < height;  ++i) {
  55.         int i_start = (int)h_offs;
  56.         int i_end = (int)(h_offs + h_step);
  57.         float w_offs = 0;
  58.         for (size_t j = 0;  j < width;  ++j) {
  59.             CImage::TPixel to = (*new_image)(i, j);
  60.             int j_start = (int)w_offs;
  61.             int j_end = (int)(w_offs + w_step);
  62.             switch (scale) {
  63.             case eScale_Average:
  64.                 {{
  65.                     //
  66.                     // average value of all pixels in the region
  67.                     //
  68.                     size_t count = 0;
  69.                     size_t vals[4];
  70.                     vals[0] = vals[1] = vals[2] = vals[3] = 0;
  71.                     for (int from_i = i_start;  from_i < i_end;  ++from_i) {
  72.                         for (int from_j = j_start;  from_j < j_end;  ++from_j) {
  73.                             CImage::TConstPixel from_pixel =
  74.                                 image(from_i, from_j);
  75.                             for (size_t k = 0;  k < image.GetDepth();  ++k) {
  76.                                 vals[k] += from_pixel[k];
  77.                             }
  78.                             ++count;
  79.                         }
  80.                     }
  81.                     for (size_t k = 0;  k < new_image->GetDepth();  ++k) {
  82.                         to[k] = (vals[k] / count) & 0xff;
  83.                     }
  84.                 }}
  85.                 break;
  86.             case eScale_Max:
  87.                 {{
  88.                     // we look for the pixel with the maximal luminance
  89.                     // to compute luminance, we borrow from PNG's
  90.                     // integer-only computation:
  91.                     //   Y = (6969 * R + 23434 * G + 2365 * B)/32768
  92.                     size_t max_lum = 0;
  93.                     for (int from_i = i_start;  from_i < i_end;  ++from_i) {
  94.                         for (int from_j = j_start;  from_j < j_end;  ++from_j) {
  95.                             CImage::TConstPixel from_pixel =
  96.                                 image(from_i, from_j);
  97.                             size_t lum = ( 6969 * from_pixel[0] +
  98.                                           23434 * from_pixel[1] +
  99.                                            2365 * from_pixel[2])/32768;
  100.                             if (lum > max_lum) {
  101.                                 max_lum = lum;
  102.                                 for (size_t k = 0;  k < image.GetDepth();  ++k) {
  103.                                     to[k] = from_pixel[k];
  104.                                 }
  105.                             }
  106.                         }
  107.                     }
  108.                 }}
  109.                 break;
  110.             case eScale_Min:
  111.                 {{
  112.                     // we look for the pixel with the maximal luminance
  113.                     // to compute luminance, we borrow from PNG's
  114.                     // integer-only computation:
  115.                     //   Y = (6969 * R + 23434 * G + 2365 * B)/32768
  116.                     size_t min_lum = kMax_Int;
  117.                     for (int from_i = i_start;  from_i < i_end;  ++from_i) {
  118.                         for (int from_j = j_start;  from_j < j_end;  ++from_j) {
  119.                             CImage::TConstPixel from_pixel =
  120.                                 image(from_i, from_j);
  121.                             size_t lum = ( 6969 * from_pixel[0] +
  122.                                           23434 * from_pixel[1] +
  123.                                            2365 * from_pixel[2])/32768;
  124.                             if (lum < min_lum) {
  125.                                 min_lum = lum;
  126.                                 for (size_t k = 0;  k < image.GetDepth();  ++k) {
  127.                                     to[k] = from_pixel[k];
  128.                                 }
  129.                             }
  130.                         }
  131.                     }
  132.                 }}
  133.                 break;
  134.             default:
  135.                 break;
  136.             }
  137.             w_offs += w_step;
  138.         }
  139.         h_offs += h_step;
  140.     }
  141.     return new_image.Release();
  142. }
  143. void CImageUtil::FlipX(CImage& image)
  144. {
  145.     const size_t scanline_size = image.GetWidth() * image.GetDepth();
  146.     const size_t depth         = image.GetDepth();
  147.     for (size_t i = 0;  i < image.GetHeight();  ++i) {
  148.         size_t start = 0;
  149.         size_t end   = scanline_size;
  150.         unsigned char* start_ptr = image.SetData() + scanline_size * i;
  151.         unsigned char* end_ptr   = image.SetData() + scanline_size * (i + 1);
  152.         end_ptr -= depth;
  153.         switch (depth) {
  154.         case 3:
  155.             for ( ; end_ptr > start_ptr;  end_ptr -= depth, start_ptr += depth) {
  156.                 std::swap(*(start_ptr    ), *(end_ptr    ));
  157.                 std::swap(*(start_ptr + 1), *(end_ptr + 1));
  158.                 std::swap(*(start_ptr + 2), *(end_ptr + 2));
  159.             }
  160.             break;
  161.         case 4:
  162.             for ( ; end_ptr > start_ptr;  end_ptr -= depth, start_ptr += depth) {
  163.                 std::swap(*(start_ptr    ), *(end_ptr    ));
  164.                 std::swap(*(start_ptr + 1), *(end_ptr + 1));
  165.                 std::swap(*(start_ptr + 2), *(end_ptr + 2));
  166.                 std::swap(*(start_ptr + 3), *(end_ptr + 3));
  167.             }
  168.             break;
  169.         default:
  170.             NCBI_THROW(CImageException, eInvalidDimension, "unhandled depth");
  171.             break;
  172.         }
  173.     }
  174. }
  175. void CImageUtil::FlipY(CImage& image)
  176. {
  177.     size_t scanline_size = image.GetWidth() * image.GetDepth();
  178.     size_t start = 0;
  179.     size_t end   = image.GetHeight() - 1;
  180.     for ( ; end > start;  --end, ++start) {
  181.         unsigned char* start_ptr = image.SetData() + scanline_size * start;
  182.         unsigned char* end_ptr   = image.SetData() + scanline_size * end;
  183.         for (size_t i = 0;  i < scanline_size;  ++i) {
  184.             std::swap(start_ptr[i], end_ptr[i]);
  185.         }
  186.     }
  187. }
  188. END_NCBI_SCOPE
  189. /*
  190.  * ===========================================================================
  191.  * $Log: image_util.cpp,v $
  192.  * Revision 1000.2  2004/06/01 19:41:49  gouriano
  193.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  194.  *
  195.  * Revision 1.4  2004/05/17 21:07:58  gorelenk
  196.  * Added include of PCH ncbi_pch.hpp
  197.  *
  198.  * Revision 1.3  2003/12/18 13:50:54  dicuccio
  199.  * Added FlipX() and FlipY() routines to flip an image about an axis
  200.  *
  201.  * Revision 1.2  2003/12/16 16:16:56  dicuccio
  202.  * Fixed compiler warnings
  203.  *
  204.  * Revision 1.1  2003/11/03 15:12:09  dicuccio
  205.  * Initial revision
  206.  *
  207.  * ===========================================================================
  208.  */