File indexing completed on 2026-04-09 07:49:02
0001 #include <iostream>
0002 #include <iomanip>
0003 #include <csignal>
0004
0005 #include <cuda_runtime.h>
0006 #include "QU.hh"
0007
0008 #include "SFrameConfig.hh"
0009 #include "SComp.h"
0010 #include "SStr.hh"
0011 #include "SPath.hh"
0012 #include "SLOG.hh"
0013 #include "NP.hh"
0014 #include "Frame.h"
0015
0016 #define SIMG_IMPLEMENTATION 1
0017 #include "SIMG.h"
0018
0019
0020 const plog::Severity Frame::LEVEL = SLOG::EnvLevel("Frame", "DEBUG" );
0021
0022 unsigned Frame::getNumPixels() const
0023 {
0024 return num_pixels ;
0025 }
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 template<typename T>
0044 T* Frame::DeviceAlloc(unsigned num_pixels, bool enabled)
0045 {
0046 return enabled ? QU::device_alloc<T>(num_pixels,"Frame::DeviceAllo:num_pixels") : nullptr ;
0047 }
0048
0049 template uchar4* Frame::DeviceAlloc<uchar4>(unsigned num_pixels, bool enabled);
0050 template float4* Frame::DeviceAlloc<float4>(unsigned num_pixels, bool enabled);
0051 template quad4* Frame::DeviceAlloc<quad4>( unsigned num_pixels, bool enabled);
0052
0053
0054 Frame::Frame(int width_, int height_, int depth_, uchar4* d_pixel_, float4* d_isect_, quad4* d_fphoton_ )
0055 :
0056 mask(SFrameConfig::FrameMask()),
0057 width(width_),
0058 height(height_),
0059 depth(depth_),
0060 channels(4),
0061 jpg_quality(SStr::GetEValue<int>("QUALITY", 50)),
0062 img(new SIMG(width, height, channels, nullptr )),
0063 num_pixels(width*height),
0064 d_pixel(d_pixel_ == nullptr ? DeviceAlloc<uchar4>(num_pixels, mask & SCOMP_PIXEL ) : d_pixel_ ),
0065 d_isect(d_isect_ == nullptr ? DeviceAlloc<float4>(num_pixels, mask & SCOMP_ISECT ) : d_isect_ ),
0066 #ifdef WITH_FRAME_PHOTON
0067 d_fphoton(d_fphoton_ == nullptr ? DeviceAlloc<quad4>( num_pixels, mask & SCOMP_FPHOTON ) : d_fphoton_)
0068 #else
0069 d_dummy(nullptr)
0070 #endif
0071 {
0072 assert( depth == 1 && num_pixels > 0 );
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 void Frame::setExternalDevicePixels(uchar4* _d_pixel )
0085 {
0086 if( _d_pixel == d_pixel ) return ;
0087
0088 if( d_pixel ) QU::device_free<uchar4>(d_pixel );
0089 d_pixel = _d_pixel ;
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 void Frame::download_(bool flip_vertical)
0103 {
0104 if(d_pixel) QU::Download<uchar4>(pixel, d_pixel, num_pixels );
0105 if(d_isect) QU::Download<float4>(isect, d_isect, num_pixels );
0106 #ifdef WITH_FRAME_PHOTON
0107 if(d_fphoton) QU::Download<quad4>(photon, d_fphoton, num_pixels );
0108 #endif
0109
0110 if(d_pixel)
0111 {
0112 img->setData( getPixelData(), flip_vertical );
0113 }
0114 }
0115
0116 void Frame::download()
0117 {
0118 download_(true);
0119 }
0120 void Frame::download_inverted()
0121 {
0122 download_(false);
0123 }
0124
0125
0126
0127 unsigned char* Frame::getPixelData() const { return d_pixel ? (unsigned char*)pixel.data() : nullptr ; }
0128 float* Frame::getIntersectData() const { return d_isect ? (float*)isect.data() : nullptr ; }
0129 #ifdef WITH_FRAME_PHOTON
0130 float* Frame::getFPhotonData() const { return d_fphoton ? (float*)fphoton.data() : nullptr ; }
0131 #endif
0132
0133 void Frame::annotate( const char* bottom_line, const char* top_line, int line_height )
0134 {
0135 img->annotate( bottom_line, top_line, line_height );
0136 }
0137
0138 void Frame::write(const char* outdir_, int quality) const
0139 {
0140 const char* outdir = SPath::Resolve(outdir_, DIRPATH);
0141 writePNG(outdir, "f_pixels.png");
0142 writeJPG(outdir, "f_pixels.jpg", quality);
0143 writeIsect(outdir, "f_isect.npy" );
0144 #ifdef WITH_FRAME_PHOTON
0145 writeFPhoton(outdir, "f_photon.npy" );
0146 #endif
0147 }
0148
0149 void Frame::writePNG(const char* dir, const char* name) const
0150 {
0151 img->writePNG(dir, name);
0152 }
0153 void Frame::writePNG(const char* path) const
0154 {
0155 img->writePNG(path);
0156 }
0157
0158 void Frame::writeJPG(const char* dir, const char* name, int quality) const
0159 {
0160 img->writeJPG(dir, name, quality > 0 ? quality : jpg_quality );
0161 }
0162 void Frame::writeJPG(const char* path, int quality) const
0163 {
0164 img->writeJPG(path, quality > 0 ? quality : jpg_quality );
0165 }
0166
0167
0168 void Frame::writeIsect( const char* dir, const char* name) const
0169 {
0170 float* isd = getIntersectData() ;
0171 if(isd) NP::Write(dir, name, isd, height, width, 4 );
0172 }
0173
0174 #ifdef WITH_FRAME_PHOTON
0175 void Frame::writeFPhoton( const char* dir, const char* name) const
0176 {
0177 float* fpd = getFPhotonData() ;
0178 if(fpd) NP::Write(dir, name, fpd, height, width, 4, 4 );
0179 }
0180 #endif
0181
0182 void Frame::snap( const char* path )
0183 {
0184 LOG(LEVEL) << "[" ;
0185
0186 LOG(LEVEL) << "[ writeJPG " ;
0187 writeJPG( path );
0188 LOG(LEVEL) << "] writeJPG " ;
0189
0190
0191 LOG(LEVEL) << "[ writeIntersectData " ;
0192 const char* fold = SPath::Dirname(path);
0193 float* isd = getIntersectData() ;
0194 if(isd) NP::Write(fold, "isect.npy", isd, height, width, 4 );
0195 LOG(LEVEL) << "] writeIntersectData " ;
0196
0197
0198 #ifdef WITH_FRAME_PHOTON
0199 LOG(LEVEL) << "[ writeFPhoton " ;
0200 float* fpd = getFPhotonData() ;
0201 if(fpd) NP::Write(fold, "fphoton.npy", fpd, height, width, 4, 4 );
0202 LOG(LEVEL) << "] writeFPhoton " ;
0203 #endif
0204
0205 LOG(LEVEL) << "]" ;
0206 }
0207
0208