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, std::uint32_t part)
00047 {
00048 if (buffer->getImagePresent(part))
00049 {
00050 timestamp=buffer->getTimestampNS();
00051
00052 width=buffer->getWidth(part);
00053 height=buffer->getHeight(part);
00054 xoffset=buffer->getXOffset(part);
00055 yoffset=buffer->getYOffset(part);
00056 xpadding=buffer->getXPadding(part);
00057 ypadding=buffer->getYPadding();
00058 frameid=buffer->getFrameID();
00059 pixelformat=buffer->getPixelFormat(part);
00060 bigendian=buffer->isBigEndian();
00061
00062 const size_t size=buffer->getSize(part);
00063
00064 pixel.reset(new uint8_t [size]);
00065
00066 memcpy(pixel.get(), reinterpret_cast<uint8_t *>(buffer->getBase(part)), size);
00067 }
00068 else
00069 {
00070 throw GenTLException("Image::Image(): Now image available.");
00071 }
00072 }
00073
00074 namespace
00075 {
00076
00081 inline unsigned char clamp8(int v)
00082 {
00083 const int v2=v<0 ? 0:v;
00084 return static_cast<unsigned char>(v2>255 ? 255:v2);
00085 }
00086
00087 }
00088
00089 void convYCbCr411toRGB(uint8_t rgb[3], const uint8_t *row, int i)
00090 {
00091 const uint32_t j=static_cast<uint32_t>((i>>2)*6);
00092 const uint32_t js=static_cast<uint32_t>(i&0x3);
00093
00094 int Y=row[j+js];
00095 if (js > 1)
00096 {
00097 Y=row[j+js+1];
00098 }
00099
00100 const int Cb=static_cast<int>(row[j+2])-128;
00101 const int Cr=static_cast<int>(row[j+5])-128;
00102
00103 const int rc=(90*Cr+32)>>6;
00104 const int gc=(-22*Cb-46*Cr+32)>>6;
00105 const int bc=(113*Cb+32)>>6;
00106
00107 rgb[0]=clamp8(Y+rc);
00108 rgb[1]=clamp8(Y+gc);
00109 rgb[2]=clamp8(Y+bc);
00110 }
00111
00112 void convYCbCr411toQuadRGB(uint8_t rgb[12], const uint8_t *row, int i)
00113 {
00114 i=(i>>2)*6;
00115
00116 const int Y[4]={row[i], row[i+1], row[i+3], row[i+4]};
00117 const int Cb=static_cast<int>(row[i+2])-128;
00118 const int Cr=static_cast<int>(row[i+5])-128;
00119
00120 const int rc=(90*Cr+32)>>6;
00121 const int gc=(-22*Cb-46*Cr+32)>>6;
00122 const int bc=(113*Cb+32)>>6;
00123
00124 for (int j=0; j<4; j++)
00125 {
00126 *rgb++=clamp8(Y[j]+rc);
00127 *rgb++=clamp8(Y[j]+gc);
00128 *rgb++=clamp8(Y[j]+bc);
00129 }
00130 }
00131
00132 void getColor(uint8_t rgb[3], const std::shared_ptr<const rcg::Image> &img,
00133 uint32_t ds, uint32_t i, uint32_t k)
00134 {
00135 i*=ds;
00136 k*=ds;
00137
00138 if (img->getPixelFormat() == Mono8)
00139 {
00140 size_t lstep=img->getWidth()+img->getXPadding();
00141 const uint8_t *p=img->getPixels()+k*lstep+i;
00142
00143 uint32_t g=0, n=0;
00144
00145 for (uint32_t kk=0; kk<ds; kk++)
00146 {
00147 for (uint32_t ii=0; ii<ds; ii++)
00148 {
00149 g+=p[ii];
00150 n++;
00151 }
00152
00153 p+=lstep;
00154 }
00155
00156 rgb[2]=rgb[1]=rgb[0]=static_cast<uint8_t>(g/n);
00157 }
00158 else if (img->getPixelFormat() == YCbCr411_8)
00159 {
00160 size_t lstep=(img->getWidth()>>2)*6+img->getXPadding();
00161 const uint8_t *p=img->getPixels()+k*lstep;
00162
00163 uint32_t r=0;
00164 uint32_t g=0;
00165 uint32_t b=0;
00166 uint32_t n=0;
00167
00168 for (uint32_t kk=0; kk<ds; kk++)
00169 {
00170 for (uint32_t ii=0; ii<ds; ii++)
00171 {
00172 uint8_t v[3];
00173 rcg::convYCbCr411toRGB(v, p, static_cast<int>(i+ii));
00174
00175 r+=v[0];
00176 g+=v[1];
00177 b+=v[2];
00178 n++;
00179 }
00180
00181 p+=lstep;
00182 }
00183
00184 rgb[0]=static_cast<uint8_t>(r/n);
00185 rgb[1]=static_cast<uint8_t>(g/n);
00186 rgb[2]=static_cast<uint8_t>(b/n);
00187 }
00188 }
00189
00190 }