void SceneValidator::ValidateTexture(Texture *texture, const FilePath &texturePathname, const String &validatedObjectName, Set<String> &errorsLog) { if(!texture) return; String path = texturePathname.GetRelativePathname(pathForChecking); String textureInfo = path + " for object: " + validatedObjectName; if(texture->IsPinkPlaceholder()) { errorsLog.insert("Can't load texture: " + textureInfo); } bool pathIsCorrect = ValidatePathname(texturePathname, validatedObjectName); if(!pathIsCorrect) { errorsLog.insert("Wrong path of: " + textureInfo); } if(!IsPowerOf2(texture->GetWidth()) || !IsPowerOf2(texture->GetHeight())) { errorsLog.insert("Wrong size of " + textureInfo); } if(texture->GetWidth() > 2048 || texture->GetHeight() > 2048) { errorsLog.insert("Texture is too big. " + textureInfo); } }
TrackArray::TrackArray( int width, int height, int cellSize ): TrackDataContainer( width, height, cellSize ) { // zapewnia, iz zarowno szerokosc, jak i wysokosc, sa potegami dwojki if( !IsPowerOf2(width) || !IsPowerOf2(height) ) throw TrackContainerException(); mpDataMatrix = allocateArray( width, height, cellSize, mCellSizeLogarithm ); }
TEST(Pow2, Basics) { for (int i = 0; i < 32; ++i) { uint32_t ui = 1u << i; EXPECT_EQ(true, IsPowerOf2(ui)); if (ui > 1) { EXPECT_EQ(false, IsPowerOf2(ui+1)); } if (ui > 2) { EXPECT_EQ(false, IsPowerOf2(ui-1)); } } }
bool GLTexture::Init( const std::string &name, int textureUnit ) { byte *pic, *picCopy; GLuint texture; int width, height, format; format = GL_RGBA; if ( EndsWith( name, ".tga" ) ) { pic = R_LoadTGA( name, width, height, format ); } else { msg_warning( "no image file with name `%s' found\n", name.c_str() ); return false; } if ( !IsPowerOf2( width ) || !IsPowerOf2( height ) ) { msg_warning0( "texture must have size in power of two\n" ); return false; } picCopy = (byte *)malloc( width * height * 4 ); _CH(glActiveTexture( GL_TEXTURE0 + textureUnit )); _CH(glGenTextures( 1, &texture )); _CH(glBindTexture( GL_TEXTURE_2D, texture )); _CH(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); _CH(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); int mipmap = 0; while ( width > 1 || height > 1 ) { _CH(glTexImage2D( GL_TEXTURE_2D, mipmap, format, width, height, 0, format, GL_UNSIGNED_BYTE, pic)); int oldWidth, oldHeight; oldWidth = width; oldHeight = height; if ( width > 1 ) { width >>= 1; } if ( height > 1 ) { height >>= 1; }
int validate_pe(void *raw, size_t raw_size, int is_exec) { PIMAGE_DOS_HEADER dos; PIMAGE_NT_HEADERS32 nt; dos = (PIMAGE_DOS_HEADER)raw; if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) ) return 0; if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0) return 0; nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); if( (uint32_t)nt < (uint32_t)raw) return 0; if(nt->Signature != IMAGE_NT_SIGNATURE) return 0; if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) return 0; if(is_exec && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)) return 0; if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return 0; if( is_exec && nt->OptionalHeader.ImageBase != 0) return 0; if(nt->OptionalHeader.SectionAlignment < 4096) { if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) return 0; } else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment) return 0; if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) || !IsPowerOf2(nt->OptionalHeader.FileAlignment)) return 0; if(nt->FileHeader.NumberOfSections > 96) return 0; return 1; }
inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m) { if (IsPowerOf2(m)) return n - ModPowerOf2(n, m); else return n - n%m; }
// ZeroTwoSequenceSampler Method Definitions ZeroTwoSequenceSampler::ZeroTwoSequenceSampler(int64_t samplesPerPixel, int nSampledDimensions) : PixelSampler(RoundUpPow2(samplesPerPixel), nSampledDimensions) { if (!IsPowerOf2(samplesPerPixel)) Warning( "Pixel samples being rounded up to power of 2 " "(from %" PRId64 " to %" PRId64 ").", samplesPerPixel, RoundUpPow2(samplesPerPixel)); }
bool SceneValidator::ValidateHeightmapPathname(const FilePath &pathForValidation, Set<String> &errorsLog) { DVASSERT_MSG(!pathForChecking.IsEmpty(), "Need to set pathname for DataSource folder"); bool pathIsCorrect = IsPathCorrectForProject(pathForValidation); if(pathIsCorrect) { String::size_type posPng = pathForValidation.GetAbsolutePathname().find(".png"); String::size_type posHeightmap = pathForValidation.GetAbsolutePathname().find(Heightmap::FileExtension()); pathIsCorrect = ((String::npos != posPng) || (String::npos != posHeightmap)); if(!pathIsCorrect) { errorsLog.insert(Format("Heightmap path %s is wrong", pathForValidation.GetAbsolutePathname().c_str())); return false; } Heightmap *heightmap = new Heightmap(); if(String::npos != posPng) { Image *image = CreateTopLevelImage(pathForValidation); pathIsCorrect = heightmap->BuildFromImage(image); SafeRelease(image); } else { pathIsCorrect = heightmap->Load(pathForValidation); } if(!pathIsCorrect) { SafeRelease(heightmap); errorsLog.insert(Format("Can't load Heightmap from path %s", pathForValidation.GetAbsolutePathname().c_str())); return false; } pathIsCorrect = IsPowerOf2(heightmap->Size() - 1); if(!pathIsCorrect) { errorsLog.insert(Format("Heightmap %s has wrong size", pathForValidation.GetAbsolutePathname().c_str())); } SafeRelease(heightmap); return pathIsCorrect; } else { errorsLog.insert(Format("Path %s is incorrect for project %s", pathForValidation.GetAbsolutePathname().c_str(), pathForChecking.GetAbsolutePathname().c_str())); } return pathIsCorrect; }
// AdaptiveSampler Method Definitions AdaptiveSampler::AdaptiveSampler(int xstart, int xend, int ystart, int yend, int mins, int maxs, const string &m, float sopen, float sclose) : Sampler(xstart, xend, ystart, yend, RoundUpPow2(maxSamples), sopen, sclose) { xPos = xPixelStart; yPos = yPixelStart; supersamplePixel = false; if (mins > maxs) std::swap(mins, maxs); if (!IsPowerOf2(mins)) { Warning("Minimum pixel samples being rounded up to power of 2"); minSamples = RoundUpPow2(mins); } else minSamples = mins; if (!IsPowerOf2(maxs)) { Warning("Maximum pixel samples being rounded up to power of 2"); maxSamples = RoundUpPow2(maxs); } else maxSamples = maxs; if (minSamples < 2) { Warning("Adaptive sampler needs at least two initial pixel samples. Using two."); minSamples = 2; } if (minSamples == maxSamples) { maxSamples *= 2; Warning("Adaptive sampler must have more maximum samples than minimum. Using %d - %d", minSamples, maxSamples); } if (m == "contrast") method = ADAPTIVE_CONTRAST_THRESHOLD; else if (m == "shapeid") method = ADAPTIVE_COMPARE_SHAPE_ID; else { Warning("Adaptive sampling metric \"%s\" unknown. Using \"contrast\".", m.c_str()); method = ADAPTIVE_CONTRAST_THRESHOLD; } sampleBuf = NULL; }
// LDSampler Method Definitions LDSampler::LDSampler(int xstart, int xend, int ystart, int yend, int ps, float sopen, float sclose) : Sampler(xstart, xend, ystart, yend, RoundUpPow2(ps), sopen, sclose) { xPos = xPixelStart; yPos = yPixelStart; if (!IsPowerOf2(ps)) { Warning("Pixel samples being rounded up to power of 2"); nPixelSamples = RoundUpPow2(ps); } else nPixelSamples = ps; sampleBuf = NULL; }
ezInt32 ezMath::PowerOfTwo_Ceil(ezUInt32 npot) { if (IsPowerOf2 (npot)) return (npot); for (int i=1; i <= (sizeof (npot) * 8); ++i) { npot >>= 1; if (npot == 1) return (npot << (i + 1)); } return (1); }
ezInt32 ezMath::PowerOfTwo_Floor(ezUInt32 npot) { if (IsPowerOf2 (npot)) return (npot); for (ezInt32 i = 1; i <= (sizeof (npot) * 8); ++i) { npot >>= 1; if (npot == 1) return (npot << i); } return (1); }
bool CubeMapTextureBrowser::ValidateTextureAndFillThumbnails(DAVA::FilePath& fp, DAVA::Vector<QImage*>& icons, DAVA::Vector<QSize>& actualSize) { bool result = true; int width = 0; int height = 0; DAVA::Vector<DAVA::String> faceNames; CubemapUtils::GenerateFaceNames(fp.GetAbsolutePathname(), faceNames); for(size_t i = 0; i < faceNames.size(); ++i) { QImage faceImage; if(!faceImage.load(faceNames[i].c_str())) //file must be present { result = false; } if(faceImage.width() != faceImage.height() || //file must be square and be power of 2 !IsPowerOf2(faceImage.width())) { result = false; } if(0 == i) { width = faceImage.width(); height = faceImage.height(); } else if(faceImage.width() != width || //all files should be the same size faceImage.height() != height) { result = false; } //scale image and put scaled version to an array QImage scaledFaceTemp = faceImage.scaled(FACE_IMAGE_SIZE, FACE_IMAGE_SIZE); QImage* scaledFace = new QImage(scaledFaceTemp); icons.push_back(scaledFace); actualSize.push_back(QSize(faceImage.width(), faceImage.height())); } return result; }
void AddPrimitive(MailboxPrim *prim) { if (nPrimitives == 1) { // Allocate initial _primitives_ array in voxel MailboxPrim **p = new MailboxPrim *[2]; p[0] = onePrimitive; primitives = p; } else if (IsPowerOf2(nPrimitives)) { // Increase size of _primitives_ array in voxel int nAlloc = 2 * nPrimitives; MailboxPrim **p = new MailboxPrim *[nAlloc]; for (u_int i = 0; i < nPrimitives; ++i) p[i] = primitives[i]; delete[] primitives; primitives = p; } primitives[nPrimitives] = prim; ++nPrimitives; }
// LDSampler Method Definitions LDSampler::LDSampler(int xstart, int xend, int ystart, int yend, int ps) : Sampler(xstart, xend, ystart, yend, RoundUpPow2(ps)) { xPos = xPixelStart - 1; yPos = yPixelStart; if (!IsPowerOf2(ps)) { Warning("Pixel samples being" " rounded up to power of 2"); pixelSamples = RoundUpPow2(ps); } else pixelSamples = ps; samplePos = pixelSamples; oneDSamples = twoDSamples = NULL; imageSamples = new float[5*pixelSamples]; lensSamples = imageSamples + 2*pixelSamples; timeSamples = imageSamples + 4*pixelSamples; n1D = n2D = 0; }
/** Open the device and do some initalisation work. @param aParams device parameters @return Epoc error code, KErrNone if everything is OK */ TInt CWinVolumeDevice::Connect(const TMediaDeviceParams& aParams) { __PRINT(_L("#-- CWinVolumeDevice::Connect()")); if(!aParams.ipDevName) { __LOG(_L("#-- CWinVolumeDevice::Connect() device name is not set!")); return KErrBadName; } __PRINTF(aParams.ipDevName); ASSERT(!HandleValid() && ipScratchBuf); //-- open the device DWORD dwAccess = GENERIC_READ; if(!aParams.iReadOnly) dwAccess |= GENERIC_WRITE; iDevHandle = CreateFileA(aParams.ipDevName, dwAccess, FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(!HandleValid()) { __LOG1(_L("#-- CWinVolumeDevice::Connect() Error creating device handle! WinErr:%d"), GetLastError()); return KErrGeneral; } //-- find out device geometry iMediaType = Unknown; iDrvGeometry.iBytesPerSector = KDefaultSectorSz; DWORD junk; //-- 1. try to query disk geometry, but it can produce wrong results for partitioned media BOOL bResult = DeviceIoControl(Handle(), IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, ipScratchBuf, KScratchBufSz, &junk, (LPOVERLAPPED)NULL); if(bResult) { const DISK_GEOMETRY& dg = (const DISK_GEOMETRY&)*ipScratchBuf; iDrvGeometry.iBytesPerSector = dg.BytesPerSector; iMediaType = dg.MediaType; __PRINT3(_L("#-- dev geometry: Cyl:%d Heads:%d Sectors:%d"), dg.Cylinders.LowPart, dg.TracksPerCylinder, dg.SectorsPerTrack); __PRINT2(_L("#-- dev geometry: MediaType:%d, bps:%d"), dg.MediaType, dg.BytesPerSector); } else { iMediaType = Unknown; iDrvGeometry.iBytesPerSector = KDefaultSectorSz; __LOG1(_L("#-- CWinVolumeDevice::Connect() IOCTL_DISK_GET_DRIVE_GEOMETRY WinError:%d !"), GetLastError()); } //-- 1.1 check "bytes per sector" value and how it corresponds to the request from parameters if(aParams.iDrvGeometry.iBytesPerSector == 0) {//-- do nothing, this parameter is not set in config file, use media's } else if(aParams.iDrvGeometry.iBytesPerSector != iDrvGeometry.iBytesPerSector) {//-- we can't set "SectorSize" value for the physical media __LOG1(_L("#-- CWinVolumeDevice::Connect() can not use 'Sec. Size' value from config:%d !"), aParams.iDrvGeometry.iBytesPerSector); Disconnect(); return KErrArgument; } ASSERT(IsPowerOf2(BytesPerSector()) && BytesPerSector() >= KDefaultSectorSz && BytesPerSector() < 4096); //-- find out partition information in order to determine volume size. bResult = DeviceIoControl(Handle(), IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, ipScratchBuf, KScratchBufSz, &junk, (LPOVERLAPPED)NULL); if(!bResult) {//-- this is a fatal error __LOG1(_L("#-- CWinVolumeDevice::Connect() IOCTL_DISK_GET_PARTITION_INFO WinError:%d !"), GetLastError()); Disconnect(); return KErrBadHandle; } //-- get partition informaton const PARTITION_INFORMATION& pi = (const PARTITION_INFORMATION&)*ipScratchBuf; TInt64 volSz = MAKE_TINT64(pi.PartitionLength.HighPart, pi.PartitionLength.LowPart); iDrvGeometry.iSizeInSectors = (TUint32)(volSz / iDrvGeometry.iBytesPerSector); __LOG3(_L("#-- partition size, bytes:%LU (%uMB), sectors:%u"), volSz, (TUint32)(volSz>>20), iDrvGeometry.iSizeInSectors); //-- check if the media size is set in coonfig and if we can use this setting. if(aParams.iDrvGeometry.iSizeInSectors == 0) {//-- do nothing, the media size is not set in the ini file, use existing media parameters } else if(aParams.iDrvGeometry.iSizeInSectors > iDrvGeometry.iSizeInSectors) {//-- requested media size in ini file is bigger than physical media, error. //-- we can't increase physical media size __LOG2(_L("#-- CWinVolumeDevice::Connect() 'MediaSizeSectors' value from config:%d > than physical:%d !"), aParams.iDrvGeometry.iSizeInSectors, iDrvGeometry.iSizeInSectors); Disconnect(); return KErrArgument; } else if(aParams.iDrvGeometry.iSizeInSectors < iDrvGeometry.iSizeInSectors) {//-- settings specify smaller media than physical one, adjust the size __PRINT1(_L("#-- reducing media size to %d sectors"), aParams.iDrvGeometry.iSizeInSectors); iDrvGeometry.iSizeInSectors = aParams.iDrvGeometry.iSizeInSectors; } ASSERT(iDrvGeometry.iSizeInSectors > KMinMediaSizeInSectors); return KErrNone; }
INT_BOOL IsPowerOf8Const(const unsigned num) { return IsPowerOf2(num) and not(num & 0xB6DB6DB6); }
bool TestSettings() { bool pass = true; cout << "\nTesting Settings...\n\n"; if (*(word32 *)"\x01\x02\x03\x04" == 0x04030201L) { #ifdef IS_LITTLE_ENDIAN cout << "passed: "; #else cout << "FAILED: "; pass = false; #endif cout << "Your machine is little endian.\n"; } else if (*(word32 *)"\x01\x02\x03\x04" == 0x01020304L) { #ifndef IS_LITTLE_ENDIAN cout << "passed: "; #else cout << "FAILED: "; pass = false; #endif cout << "Your machine is big endian.\n"; } else { cout << "FAILED: Your machine is neither big endian nor little endian.\n"; pass = false; } if (sizeof(byte) == 1) cout << "passed: "; else { cout << "FAILED: "; pass = false; } cout << "sizeof(byte) == " << sizeof(byte) << endl; if (sizeof(word16) == 2) cout << "passed: "; else { cout << "FAILED: "; pass = false; } cout << "sizeof(word16) == " << sizeof(word16) << endl; if (sizeof(word32) == 4) cout << "passed: "; else { cout << "FAILED: "; pass = false; } cout << "sizeof(word32) == " << sizeof(word32) << endl; #ifdef WORD64_AVAILABLE if (sizeof(word64) == 8) cout << "passed: "; else { cout << "FAILED: "; pass = false; } cout << "sizeof(word64) == " << sizeof(word64) << endl; #elif defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) if (sizeof(dword) >= 8) { cout << "FAILED: sizeof(dword) >= 8, but WORD64_AVAILABLE not defined" << endl; pass = false; } else cout << "passed: word64 not available" << endl; #endif #ifdef CRYPTOPP_WORD128_AVAILABLE if (sizeof(word128) == 16) cout << "passed: "; else { cout << "FAILED: "; pass = false; } cout << "sizeof(word128) == " << sizeof(word128) << endl; #endif if (sizeof(word) == 2*sizeof(hword) #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE && sizeof(dword) == 2*sizeof(word) #endif ) cout << "passed: "; else { cout << "FAILED: "; pass = false; } cout << "sizeof(hword) == " << sizeof(hword) << ", sizeof(word) == " << sizeof(word); #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE cout << ", sizeof(dword) == " << sizeof(dword); #endif cout << endl; bool hasMMX = HasMMX(); bool hasISSE = HasISSE(); bool hasSSE2 = HasSSE2(); bool hasSSSE3 = HasSSSE3(); bool isP4 = IsP4(); int cacheLineSize = GetCacheLineSize(); if ((isP4 && (!hasMMX || !hasSSE2)) || (hasSSE2 && !hasMMX) || (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize))) { cout << "FAILED: "; pass = false; } else cout << "passed: "; cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize; if (!pass) { cout << "Some critical setting in config.h is in error. Please fix it and recompile." << endl; abort(); } return pass; }
inline T2 ModPowerOf2(const T1 &a, const T2 &b) { assert(IsPowerOf2(b)); return T2(a) & (b-1); }
inline bool IsAlignedOn(const void *p, unsigned int alignment) { return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0); }
void MetropolisRenderer::Render(const Scene *scene) { PBRT_MLT_STARTED_RENDERING(); if (scene->lights.size() > 0) { int x0, x1, y0, y1; camera->film->GetPixelExtent(&x0, &x1, &y0, &y1); float t0 = camera->shutterOpen, t1 = camera->shutterClose; Distribution1D *lightDistribution = ComputeLightSamplingCDF(scene); if (directLighting != NULL) { PBRT_MLT_STARTED_DIRECTLIGHTING(); // Compute direct lighting before Metropolis light transport if (nDirectPixelSamples > 0) { LDSampler sampler(x0, x1, y0, y1, nDirectPixelSamples, t0, t1); Sample *sample = new Sample(&sampler, directLighting, NULL, scene); vector<Task *> directTasks; int nDirectTasks = max(32 * NumSystemCores(), (camera->film->xResolution * camera->film->yResolution) / (16*16)); nDirectTasks = RoundUpPow2(nDirectTasks); ProgressReporter directProgress(nDirectTasks, "Direct Lighting"); for (int i = 0; i < nDirectTasks; ++i) directTasks.push_back(new SamplerRendererTask(scene, this, camera, directProgress, &sampler, sample, false, i, nDirectTasks)); std::reverse(directTasks.begin(), directTasks.end()); EnqueueTasks(directTasks); WaitForAllTasks(); for (uint32_t i = 0; i < directTasks.size(); ++i) delete directTasks[i]; delete sample; directProgress.Done(); } camera->film->WriteImage(); PBRT_MLT_FINISHED_DIRECTLIGHTING(); } // Take initial set of samples to compute $b$ PBRT_MLT_STARTED_BOOTSTRAPPING(nBootstrap); RNG rng(0); MemoryArena arena; vector<float> bootstrapI; vector<PathVertex> cameraPath(maxDepth, PathVertex()); vector<PathVertex> lightPath(maxDepth, PathVertex()); float sumI = 0.f; bootstrapI.reserve(nBootstrap); MLTSample sample(maxDepth); for (uint32_t i = 0; i < nBootstrap; ++i) { // Generate random sample and path radiance for MLT bootstrapping float x = Lerp(rng.RandomFloat(), x0, x1); float y = Lerp(rng.RandomFloat(), y0, y1); LargeStep(rng, &sample, maxDepth, x, y, t0, t1, bidirectional); Spectrum L = PathL(sample, scene, arena, camera, lightDistribution, &cameraPath[0], &lightPath[0], rng); // Compute contribution for random sample for MLT bootstrapping float I = ::I(L); sumI += I; bootstrapI.push_back(I); arena.FreeAll(); } float b = sumI / nBootstrap; PBRT_MLT_FINISHED_BOOTSTRAPPING(b); Info("MLT computed b = %f", b); // Select initial sample from bootstrap samples float contribOffset = rng.RandomFloat() * sumI; rng.Seed(0); sumI = 0.f; MLTSample initialSample(maxDepth); for (uint32_t i = 0; i < nBootstrap; ++i) { float x = Lerp(rng.RandomFloat(), x0, x1); float y = Lerp(rng.RandomFloat(), y0, y1); LargeStep(rng, &initialSample, maxDepth, x, y, t0, t1, bidirectional); sumI += bootstrapI[i]; if (sumI > contribOffset) break; } // Launch tasks to generate Metropolis samples uint32_t nTasks = largeStepsPerPixel; uint32_t largeStepRate = nPixelSamples / largeStepsPerPixel; Info("MLT running %d tasks, large step rate %d", nTasks, largeStepRate); ProgressReporter progress(nTasks * largeStepRate, "Metropolis"); vector<Task *> tasks; Mutex *filmMutex = Mutex::Create(); Assert(IsPowerOf2(nTasks)); uint32_t scramble[2] = { rng.RandomUInt(), rng.RandomUInt() }; uint32_t pfreq = (x1-x0) * (y1-y0); for (uint32_t i = 0; i < nTasks; ++i) { float d[2]; Sample02(i, scramble, d); tasks.push_back(new MLTTask(progress, pfreq, i, d[0], d[1], x0, x1, y0, y1, t0, t1, b, initialSample, scene, camera, this, filmMutex, lightDistribution)); } EnqueueTasks(tasks); WaitForAllTasks(); for (uint32_t i = 0; i < tasks.size(); ++i) delete tasks[i]; progress.Done(); Mutex::Destroy(filmMutex); delete lightDistribution; } camera->film->WriteImage(); PBRT_MLT_FINISHED_RENDERING(); }
/** Check if given number is a power of d where d is a power of 2 * * @reference https://www.geeksforgeeks.org/check-given-number-power-d-d-power-2/ * * Given an integer n, find whether it is a power of d or not, * where d is itself a power of 2. */ INT_BOOL IsPowerOfPowerOf2(const unsigned n, const unsigned d) { return IsPowerOf2(n) and (CountTrailingZerosLinear(n) % static_cast<unsigned>(log2(d))) == 0; }