Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "image.h"
00037
00038 #include "exception.h"
00039 #include "pixel_formats.h"
00040
00041 #include <cstring>
00042
00043 namespace rcg
00044 {
00045
00046 Image::Image(const Buffer *buffer)
00047 {
00048 if (buffer->getImagePresent())
00049 {
00050 timestamp=buffer->getTimestampNS();
00051
00052 width=buffer->getWidth();
00053 height=buffer->getHeight();
00054 xoffset=buffer->getXOffset();
00055 yoffset=buffer->getYOffset();
00056 xpadding=buffer->getXPadding();
00057 ypadding=buffer->getYPadding();
00058 frameid=buffer->getFrameID();
00059 pixelformat=buffer->getPixelFormat();
00060 bigendian=buffer->isBigEndian();
00061
00062 const size_t size=buffer->getSizeFilled();
00063 const size_t offset=buffer->getImageOffset();
00064
00065 pixel.reset(new uint8_t [size-offset]);
00066
00067 memcpy(pixel.get(), reinterpret_cast<uint8_t *>(buffer->getBase())+offset, size-offset);
00068 }
00069 else
00070 {
00071 throw GenTLException("Image::Image(): Now image available.");
00072 }
00073 }
00074
00075 namespace
00076 {
00077
00082 inline unsigned char clamp8(int v)
00083 {
00084 const int v2=v<0 ? 0:v;
00085 return static_cast<unsigned char>(v2>255 ? 255:v2);
00086 }
00087
00088 }
00089
00090 void convYCbCr411toRGB(uint8_t rgb[3], const uint8_t *row, int i)
00091 {
00092 const uint32_t j=(i>>2)*6;
00093 const uint32_t js=i&0x3;
00094
00095 int Y=row[j+js];
00096 if (js > 1)
00097 {
00098 Y=row[j+js+1];
00099 }
00100
00101 const int Cb=static_cast<int>(row[j+2])-128;
00102 const int Cr=static_cast<int>(row[j+5])-128;
00103
00104 const int rc=(90*Cr+32)>>6;
00105 const int gc=(-22*Cb-46*Cr+32)>>6;
00106 const int bc=(113*Cb+32)>>6;
00107
00108 rgb[0]=clamp8(Y+rc);
00109 rgb[1]=clamp8(Y+gc);
00110 rgb[2]=clamp8(Y+bc);
00111 }
00112
00113 void convYCbCr411toQuadRGB(uint8_t rgb[12], const uint8_t *row, int i)
00114 {
00115 i=(i>>2)*6;
00116
00117 const int Y[4]={row[i], row[i+1], row[i+3], row[i+4]};
00118 const int Cb=static_cast<int>(row[i+2])-128;
00119 const int Cr=static_cast<int>(row[i+5])-128;
00120
00121 const int rc=(90*Cr+32)>>6;
00122 const int gc=(-22*Cb-46*Cr+32)>>6;
00123 const int bc=(113*Cb+32)>>6;
00124
00125 for (int j=0; j<4; j++)
00126 {
00127 *rgb++=clamp8(Y[j]+rc);
00128 *rgb++=clamp8(Y[j]+gc);
00129 *rgb++=clamp8(Y[j]+bc);
00130 }
00131 }
00132
00133 void getColor(uint8_t rgb[3], const std::shared_ptr<const rcg::Image> &img,
00134 uint32_t ds, uint32_t i, uint32_t k)
00135 {
00136 i*=ds;
00137 k*=ds;
00138
00139 if (img->getPixelFormat() == Mono8)
00140 {
00141 size_t lstep=img->getWidth()+img->getXPadding();
00142 const uint8_t *p=img->getPixels()+k*lstep+i;
00143
00144 uint32_t g=0, n=0;
00145
00146 for (uint32_t kk=0; kk<ds; kk++)
00147 {
00148 for (uint32_t ii=0; ii<ds; ii++)
00149 {
00150 g+=p[ii];
00151 n++;
00152 }
00153
00154 p+=lstep;
00155 }
00156
00157 rgb[2]=rgb[1]=rgb[0]=g/n;
00158 }
00159 else if (img->getPixelFormat() == YCbCr411_8)
00160 {
00161 size_t lstep=(img->getWidth()>>2)*6+img->getXPadding();
00162 const uint8_t *p=img->getPixels()+k*lstep;
00163
00164 uint32_t r=0;
00165 uint32_t g=0;
00166 uint32_t b=0;
00167 uint32_t n=0;
00168
00169 for (uint32_t kk=0; kk<ds; kk++)
00170 {
00171 for (uint32_t ii=0; ii<ds; ii++)
00172 {
00173 uint8_t v[3];
00174 rcg::convYCbCr411toRGB(v, p, i+ii);
00175
00176 r+=v[0];
00177 g+=v[1];
00178 b+=v[2];
00179 n++;
00180 }
00181
00182 p+=lstep;
00183 }
00184
00185 rgb[0]=r/n;
00186 rgb[1]=g/n;
00187 rgb[2]=b/n;
00188 }
00189 }
00190
00191 }