void Image::GetPixel( int iX, int iY, float oColor[4] ){// находим в какой странице находится нужный пиксель// переводим iX, iY в координаты страницы ImgPage * thePage = this->GetPage(&iX, &iY);// если страница не загружена - загружаем ее if (!thePage->mData) LoadPageFromDisk(thePage);// получаем указатель на нужный пиксель unsigned char * pixel = (unsigned char *) thePage->mData + iY * mPageWidthBytes + iX * mPixelSize;// получаем из пикселя 4-х байтные float switch (mDataFormat) { case ARGB8: oColor[0] = pixel[0] / 255.0f; oColor[1] = pixel[1] / 255.0f; oColor[2] = pixel[2] / 255.0f; oColor[3] = pixel[3] / 255.0f; break; case ARGB16: ... break; ... }}
void GetPixel( ... ){ .... // <--- сейчас 1-й процессор выполняет команду здесь, mUsage еще = 0 ++thePage->mUsage; ... // read pixel --thePage->mUsage;}
void LoadPageFromDisk( ... ){ .... if (!theLastPage->mUsage) { // <--- сейчас 2-й процессор выполняет команду здесь, mUsage еще = 0 ... theLastPage->mData = 0; // mark page as swapped .... } ...}
C++ (Qt)void GetPixel( ... ){ ImgPage page = GetPage(...); // Вернули страницу (если надо загрузили страницу) ...} // при выходе из функции объект page разрушается и в деструктор уменьшает счетчик
C++ (Qt)class Page{public: Page() : m_cntUsed( 0 ) {} void incCntUsed() { QMutexLocker lock( m_mutex ); ++m_mutex; } void decCntUsed() { QMutexLocker lock( m_mutex ); --m_mutex; } quint32 cntUsed() const { QMutexLocker lock( m_mutex ); return m_mutex; } private: QByteArray m_data; quint32 m_cntUsed; mutable QMutex m_mutex;}; class ImgPageCache{public: Page *getPage( int x ); private: QMap<int, Page*> m_cache; mutable QMutex m_mutex;}; Page *ImgPageCache::getPage( int x ){ Page *page = 0; QMutexLocker lock( m_mutex ); if( m_cache.contains( x ) ) { // Страница в кеше page = m_cache[ x ]; page->incCntUsed(); return page; } lock.unlock(); // Страницы нет в кеше, загружаем... page = LoadPage( ... ); lock.relock(); m_cache.insert( x, page ); page->incCntUsed(); return page;}
C++ (Qt)Page *ImgPageCache::getPage( int x ){ Page *page = 0; QMutexLocker lock( m_mutex ); if( m_cache.contains( x ) ) {
void Image::Sample( int iX, int iY, int sample, FColor & color ){ int i, j, num = 0; FColor temp; oColor = 0.0f; for (j = iY - sample; j <= iY + sample; ++j) for (i = iX - sample; i <= iX + sample; ++i) { if (CheckPixel(i, j) { GetPixel(i, j, temp); oColor += temp; ++num; } } if (num) oColor /= num;}