/** * Shifts the pixels in this Image a given number of pixels to upward. * * @param n The number of pixels to shift. * * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER. * * @code * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart * MicroBitImage i(10,5,heart); * i.shiftUp(1); * @endcode */ int MicroBitImage::shiftUp(int16_t n) { uint8_t *pOut, *pIn; if (n <= 0 ) return MICROBIT_INVALID_PARAMETER; if(n >= getHeight()) { clear(); return MICROBIT_OK; } pOut = getBitmap(); pIn = getBitmap()+getWidth()*n; for (int y = 0; y < getHeight(); y++) { // Copy, and blank fill the leftmost column. if (y < getHeight()-n) memcpy(pOut, pIn, getWidth()); else memclr(pOut, getWidth()); pIn += getWidth(); pOut += getWidth(); } return MICROBIT_OK; }
void ImageData::updateData(const Util::Bitmap & _bitmap) { if(_bitmap.getPixelFormat() != getBitmap()->getPixelFormat()){ WARN("updateData: Different pixel formats!"); return; } std::copy(_bitmap.data(), _bitmap.data() + std::min<size_t>(_bitmap.getDataSize(), getBitmap()->getDataSize()), getLocalData()); dataChanged(); }
void GLTexture::refresh() { Bitmap *bitmap = getBitmap(); /* Bind to the texture */ glBindTexture(m_glType, m_id); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (m_type == ETexture1D) { Assert((math::isPowerOfTwo(m_size.x) && m_size.y == 1) || (math::isPowerOfTwo(m_size.y) && m_size.x == 1)); if (isMipMapped()) { /* Let GLU generate mipmaps for us */ gluBuild1DMipmaps(m_glType, m_internalFormat, m_size.x == 1 ? m_size.y : m_size.x, m_format, m_dataFormat, bitmap->getData()); } else { } glTexImage1D(m_glType, 0, m_internalFormat, m_size.x == 1 ? m_size.y : m_size.x, 0, m_format, m_dataFormat, bitmap->getData()); } else if (m_type == ETexture2D) { /* Anisotropic texture filtering */ float anisotropy = (float) getMaxAnisotropy(); if (isMipMapped() && m_filterType == EMipMapLinear && anisotropy > 1.0f) glTexParameterf(m_glType, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); glTexImage2D(m_glType, 0, m_internalFormat, m_size.x, m_size.y, 0, m_format, m_dataFormat, bitmap->getData()); } else if (m_type == ETextureCubeMap) { Assert(bitmap != NULL); Assert(bitmap->getWidth() == bitmap->getHeight()); Assert(math::isPowerOfTwo(bitmap->getWidth())); if (isMipMapped()) glTexParameteri(m_glType, GL_GENERATE_MIPMAP, GL_TRUE); for (int i=0; i<6; i++) { Bitmap *bitmap = getBitmap(i); GLuint pos; switch (i) { case ECubeMapPositiveX: pos = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break; case ECubeMapNegativeX: pos = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break; case ECubeMapPositiveY: pos = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break; case ECubeMapNegativeY: pos = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break; case ECubeMapPositiveZ: pos = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break; case ECubeMapNegativeZ: pos = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break; default: Log(EError, "Unknown cube map index"); return; }; glTexImage2D(pos, 0, m_internalFormat, bitmap->getWidth(), bitmap->getHeight(), 0, m_format, m_dataFormat, bitmap->getData()); } } else { Log(EError, "Unknown texture type!"); } if (isMipMapped()) glGenerateMipmapEXT(m_glType); }
//BEGIN - OutputDev hooked calls void KPDFOutputDev::endPage() { SplashOutputDev::endPage(); int bh = getBitmap()->getHeight(), bw = getBitmap()->getWidth(); // TODO The below loop can be avoided if using the code that is commented here and // we change splashModeRGB8 to splashModeARGB8 the problem is that then bug101800.pdf // does not work /* SplashColorPtr dataPtr = getBitmap()->getDataPtr(); // construct a qimage SHARING the raw bitmap data in memory QImage * img = new QImage( dataPtr, bw, bh, 32, 0, 0, QImage::IgnoreEndian );*/ QImage * img = new QImage( bw, bh, 32 ); SplashColorPtr pixel = new Guchar[4]; for (int i = 0; i < bw; i++) { for (int j = 0; j < bh; j++) { getBitmap()->getPixel(i, j, pixel); img->setPixel( i, j, qRgb( pixel[0], pixel[1], pixel[2] ) ); } } delete [] pixel; // use the QImage or convert it immediately to QPixmap for better // handling and memory unloading if ( m_qtThreadSafety ) { delete m_image; // it may happen (in fact it doesn't) that we need a rescaling if ( bw != m_pixmapWidth && bh != m_pixmapHeight ) m_image = new QImage( img->smoothScale( m_pixmapWidth, m_pixmapHeight ) ); else // dereference image from the xpdf memory m_image = new QImage( img->copy() ); } else { delete m_pixmap; // it may happen (in fact it doesn't) that we need a rescaling if ( bw != m_pixmapWidth || bh != m_pixmapHeight ) m_pixmap = new QPixmap( img->smoothScale( m_pixmapWidth, m_pixmapHeight ) ); else m_pixmap = new QPixmap( *img ); } // destroy the shared descriptor and (###) unload underlying xpdf bitmap delete img; SplashOutputDev::startPage( 0, NULL ); }
void SkOSWindow::doPaint() { if (NULL == fUnixWindow.fDisplay) { return; } // If we are drawing with GL, we don't need XPutImage. if (NULL != fUnixWindow.fGLContext) { return; } // Draw the bitmap to the screen. const SkBitmap& bitmap = getBitmap(); int width = bitmap.width(); int height = bitmap.height(); XImage image; if (!convertBitmapToXImage(image, bitmap)) { return; } XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &image, 0, 0, // src x,y 0, 0, // dst x,y width, height); }
/** * Crops the image to the given dimensions. * * @param startx the location to start the crop in the x-axis * * @param starty the location to start the crop in the y-axis * * @param width the width of the desired cropped region * * @param height the height of the desired cropped region * * @code * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart * MicroBitImage i(10,5,heart); * i.crop(0,0,2,2).toString() // "0,1\n1,1\n" * @endcode */ MicroBitImage MicroBitImage::crop(int startx, int starty, int cropWidth, int cropHeight) { int newWidth = startx + cropWidth; int newHeight = starty + cropHeight; if (newWidth >= getWidth() || newWidth <=0) newWidth = getWidth(); if (newHeight >= getHeight() || newHeight <= 0) newHeight = getHeight(); //allocate our storage. uint8_t cropped[newWidth * newHeight]; //calculate the pointer to where we want to begin cropping uint8_t *copyPointer = getBitmap() + (getWidth() * starty) + startx; //get a reference to our storage uint8_t *pastePointer = cropped; //go through row by row and select our image. for (int i = starty; i < newHeight; i++) { memcpy(pastePointer, copyPointer, newWidth); copyPointer += getWidth(); pastePointer += newHeight; } return MicroBitImage(newWidth, newHeight, cropped); }
int64 Filesystem::calculateUsedSpace(void) { const unsigned char *bm=getBitmap(); uint64 blocks1=getSize()/getBlocksize(); unsigned int tadd=(unsigned int)(blocks1/8);; if( blocks1%8>0) ++tadd; const unsigned char *target=bm+tadd; int64 used_blocks=0; uint64 blocknum=0; while(bm!=target) { const unsigned char b=*bm; for(int i=0;i<8;++i) { if(blocknum>=blocks1) break; if( (b & (1<<i))>0 ) { ++used_blocks; } ++blocknum; } ++bm; } return used_blocks*getBlocksize(); }
string Card::toString() { stringstream out; out << ", Value: " << getValue() << ", Suit: " << getSuit() << ", Bitmap: " << getBitmap() << endl; return out.str(); }
/** * Pastes a given bitmap at the given co-ordinates. * * Any pixels in the relevant area of this image are replaced. * * @param image The MicroBitImage to paste. * * @param x The leftmost X co-ordinate in this image where the given image should be pasted. Defaults to 0. * * @param y The uppermost Y co-ordinate in this image where the given image should be pasted. Defaults to 0. * * @param alpha set to 1 if transparency clear pixels in given image should be treated as transparent. Set to 0 otherwise. Defaults to 0. * * @return The number of pixels written. * * @code * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart * MicroBitImage i(10,5,heart); // a big heart * i.paste(i, -5, 0); // a small heart * @endcode */ int MicroBitImage::paste(const MicroBitImage &image, int16_t x, int16_t y, uint8_t alpha) { uint8_t *pIn, *pOut; int cx, cy; int pxWritten = 0; // Sanity check. // We permit writes that overlap us, but ones that are clearly out of scope we can filter early. if (x >= getWidth() || y >= getHeight() || x+image.getWidth() <= 0 || y+image.getHeight() <= 0) return 0; //Calculate the number of byte we need to copy in each dimension. cx = x < 0 ? min(image.getWidth() + x, getWidth()) : min(image.getWidth(), getWidth() - x); cy = y < 0 ? min(image.getHeight() + y, getHeight()) : min(image.getHeight(), getHeight() - y); // Calculate sane start pointer. pIn = image.ptr->data; pIn += (x < 0) ? -x : 0; pIn += (y < 0) ? -image.getWidth()*y : 0; pOut = getBitmap(); pOut += (x > 0) ? x : 0; pOut += (y > 0) ? getWidth()*y : 0; // Copy the image, stride by stride // If we want primitive transparecy, we do this byte by byte. // If we don't, use a more efficient block memory copy instead. Every little helps! if (alpha) { for (int i=0; i<cy; i++) { for (int j=0; j<cx; j++) { // Copy this byte if appropriate. if (*(pIn+j) != 0){ *(pOut+j) = *(pIn+j); pxWritten++; } } pIn += image.getWidth(); pOut += getWidth(); } } else { for (int i=0; i<cy; i++) { memcpy(pOut, pIn, cx); pxWritten += cx; pIn += image.getWidth(); pOut += getWidth(); } } return pxWritten; }
void SkOSWindow::doPaint() { if (!fUnixWindow.fDisplay) return; // Draw the bitmap to the screen. const SkBitmap& bitmap = getBitmap(); int width = bitmap.width(); int height = bitmap.height(); XImage image; if (!convertBitmapToXImage(image, bitmap)) return; XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &image, 0, 0, 0, 0, width, height); }
Font* Resource::getFont( const std::string& filename, unsigned int textColor ) { std::string key = filename + toString(textColor); if (mFonts.find(key) == mFonts.end()) { Font* font = new Font(getBitmap(filename, textColor), ' ', 'z'); mFonts[key] = font; } return mFonts[key]; }
bool Filesystem::hasBlock(int64 pBlock) { const unsigned char *bitmap=getBitmap(); int64 blocksize=getBlocksize(); size_t bitmap_byte=(size_t)(pBlock/8); size_t bitmap_bit=pBlock%8; unsigned char b=bitmap[bitmap_byte]; bool has_bit=((b & (1<<bitmap_bit))>0); return has_bit; }
int firstOpenBlock() { if(pcb->freeBlockCount ==0) // If there is no free blocks left in the filesystem { printf("ERROR: Filesystem is FULL :(\n"); // Print error message to stdout return -1; // Return an error -1 } for (int i=0; i < NUM_BLOCKS; i++) if(getBitmap(i) == 0) // If the value for the block in the bitmap is 0 return i; // Return index of the first free block printf("ERROR: firstOpenBlock()\n"); // Print error message to stdout return -1; // Return an error -1 }
void GLTexture::refresh(const Point2i &offset, const Vector2i &size) { Assert(m_type == ETexture2D); glBindTexture(m_glType, m_id); Bitmap *bitmap = getBitmap(); uint8_t *ptr = bitmap->getUInt8Data() + bitmap->getBytesPerPixel() * (offset.x + offset.y * bitmap->getWidth()); glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap->getWidth()); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D(m_glType, 0, offset.x, offset.y, size.x, size.y, m_format, m_dataFormat, ptr); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); }
char* Filesystem::readBlockInt(int64 pBlock, bool use_readahead) { const unsigned char *bitmap=getBitmap(); int64 blocksize=getBlocksize(); size_t bitmap_byte=(size_t)(pBlock/8); size_t bitmap_bit=pBlock%8; unsigned char b=bitmap[bitmap_byte]; bool has_bit=((b & (1<<bitmap_bit))>0); if(!has_bit) return NULL; if (read_ahead_mode == IFSImageFactory::EReadaheadMode_Overlapped) { SNextBlock* next_block = completionGetBlock(pBlock); if (next_block == NULL) return NULL; used_next_blocks[next_block->buffer] = next_block; return next_block->buffer; } else if (read_ahead_mode == IFSImageFactory::EReadaheadMode_Thread) { return readahead_thread->getBlock(pBlock); } else { bool b=dev->Seek(pBlock*blocksize); if(!b) { Server->Log("Seeking in device failed -1", LL_ERROR); has_error=true; return NULL; } char* buf = getBuffer(); if(!readFromDev(buf, (_u32)blocksize) ) { Server->Log("Reading from device failed -1", LL_ERROR); has_error=true; return NULL; } return buf; } }
__unused JNIEXPORT jlong JNICALL Java_pl_droidsonroids_gif_GifInfoHandle_renderFrame(JNIEnv *env, jclass __unused handleClass, jlong gifInfo, jobject jbitmap) { GifInfo *info = (GifInfo *) (intptr_t) gifInfo; if (info == NULL) return -1; time_t renderStartTime = getRealTime(); void *pixels; if (lockPixels(env, jbitmap, info, &pixels) != 0) { return 0; } DDGifSlurp(info, true); const uint_fast16_t frameDuration = getBitmap((argb *) pixels, info); unlockPixels(env, jbitmap); return calculateInvalidationDelay(info, renderStartTime, frameDuration); }
/************************************************************** *** ** IconProvider --- createDasaImageList *** ***************************************************************/ wxImageList *IconProvider::createDasaImageList() { const int max_image = 15; const int imageIdList[max_image] = { BITMAP_DASA, BITMAP_DASA_FOLDER, BITMAP_MAHADASA, BITMAP_DASATREE1, BITMAP_DASATREE2, BITMAP_DASATREE3, BITMAP_DASATREE4, BITMAP_DASATREE5, BITMAP_DASA_FOLDERE, BITMAP_MAHADASAE, BITMAP_DASATREE1E, BITMAP_DASATREE2E, BITMAP_DASATREE3E, BITMAP_DASATREE4E, BITMAP_DASATREE5E }; wxImageList *imagelist; imagelist = new wxImageList( 24, 24, true ); for ( int i = 0; i < max_image; i++ ) { imagelist->Add( getBitmap( imageIdList[i] )); } return imagelist; }
/************************************************************** *** ** IconProvider --- createImageList *** ***************************************************************/ wxImageList *IconProvider::createAppWindowImageList( const bool &smallList ) { const int max_image = 21; const int imageIdList[max_image] = { BITMAP_HORA, BITMAP_SVIEW, BITMAP_MVIEW, BITMAP_DASA, BITMAP_TRANSIT, BITMAP_EPHEM, BITMAP_URANIAN, BITMAP_CHART, BITMAP_CHART9, BITMAP_WCHART, BITMAP_PARTNER, BITMAP_SBC, BITMAP_GRAPHICALDASA, BITMAP_ECLIPSE, BITMAP_YOGA, BITMAP_SOLAR, BITMAP_VARGA, BITMAP_SHADBALA, BITMAP_ASHTAKAVARGA, BITMAP_YOGAEDITOR, BITMAP_TEXT }; wxImageList *imagelist; if ( smallList ) imagelist = new wxImageList( 16, 16, true ); else imagelist = new wxImageList( 24, 24, true ); for ( int i = 0; i < max_image; i++ ) { if ( smallList ) imagelist->Add( getMenuBitmap( imageIdList[i] )); else imagelist->Add( getBitmap( imageIdList[i] )); } return imagelist; }
void SkExampleWindow::draw(SkCanvas* canvas) { if (NULL != fCurrExample) { fCurrExample->draw(canvas); } if (fType == kGPU_DeviceType) { SkASSERT(NULL != fContext); fContext->flush(); } if (fType == kRaster_DeviceType) { // need to send the raster bits to the (gpu) window fContext->setRenderTarget(fRenderTarget); const SkBitmap& bm = getBitmap(); fRenderTarget->writePixels(0, 0, bm.width(), bm.height(), kSkia8888_GrPixelConfig, bm.getPixels(), bm.rowBytes()); } INHERITED::present(); }
/** * Converts the bitmap to a csv ManagedString. * * @code * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart * MicroBitImage i(10,5,heart); * uBit.serial.printString(i.toString()); // "0,1,0,1,0,0,0,0,0,0\n..." * @endcode */ ManagedString MicroBitImage::toString() { //width including commans and \n * height int stringSize = getSize() * 2; //plus one for string terminator char parseBuffer[stringSize + 1]; parseBuffer[stringSize] = '\0'; uint8_t *bitmapPtr = getBitmap(); int parseIndex = 0; int widthCount = 0; while (parseIndex < stringSize) { if(*bitmapPtr) parseBuffer[parseIndex] = '1'; else parseBuffer[parseIndex] = '0'; parseIndex++; if(widthCount == getWidth()-1) { parseBuffer[parseIndex] = '\n'; widthCount = 0; } else { parseBuffer[parseIndex] = ','; widthCount++; } parseIndex++; bitmapPtr++; } return ManagedString(parseBuffer); }
SkJS::SkJS(void* hwnd) : SkOSWindow(hwnd) { if ((fRuntime = JS_NewRuntime(0x100000)) == NULL) { SkASSERT(0); return; } if ((fContext = JS_NewContext(fRuntime, 0x1000)) == NULL) { SkASSERT(0); return; } ; if ((fGlobal = JS_NewObject(fContext, &global_class, NULL, NULL)) == NULL) { SkASSERT(0); return; } if (JS_InitStandardClasses(fContext, fGlobal) == NULL) { SkASSERT(0); return; } setConfig(SkBitmap::kARGB32_Config); updateSize(); setVisibleP(true); InitializeDisplayables(getBitmap(), fContext, fGlobal, NULL); }
/** * Shifts the pixels in this Image a given number of pixels to the right. * * @param n The number of pixels to shift. * * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER. * * @code * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart * MicroBitImage i(10,5,heart); // a big heart * i.shiftLeft(5); // a small heart * i.shiftRight(5); // a big heart * @endcode */ int MicroBitImage::shiftRight(int16_t n) { uint8_t *p = getBitmap(); int pixels = getWidth()-n; if (n <= 0) return MICROBIT_INVALID_PARAMETER; if(n >= getWidth()) { clear(); return MICROBIT_OK; } for (int y = 0; y < getHeight(); y++) { // Copy, and blank fill the leftmost column. memmove(p+n, p, pixels); memclr(p, n); p += getWidth(); } return MICROBIT_OK; }
Chunk::iterator Chunk::begin() { return iterator(this, iterator::findNextIndex(getBitmap(), 0, getBitmap().bitCount())); }
/** * Create a copy of the image bitmap. Used particularly, when isReadOnly() is true. * * @return an instance of MicroBitImage which can be modified independently of the current instance */ MicroBitImage MicroBitImage::clone() { return MicroBitImage(getWidth(), getHeight(), getBitmap()); }
Chunk::iterator Chunk::end() { return iterator(this, getBitmap().bitCount()); }
void GLTexture::download(Bitmap *bitmap) { if (bitmap == NULL) bitmap = getBitmap(); Assert(bitmap != NULL); activateTarget(); GLenum format, dataFormat; switch (bitmap->getComponentFormat()) { case Bitmap::EUInt8: dataFormat = GL_UNSIGNED_BYTE; break; case Bitmap::EUInt16: dataFormat = GL_UNSIGNED_SHORT; break; case Bitmap::EUInt32: dataFormat = GL_UNSIGNED_INT; break; case Bitmap::EFloat16: dataFormat = GL_HALF_FLOAT_ARB; break; case Bitmap::EFloat32: dataFormat = GL_FLOAT; break; case Bitmap::EFloat64: dataFormat = GL_DOUBLE; break; default: Log(EError, "GLTexture::download(): Unknown/unsupported component format %i!", (int) bitmap->getComponentFormat()); return; } switch (bitmap->getPixelFormat()) { case Bitmap::ELuminance: if (m_fbType == EDepthBuffer) format = GL_DEPTH_COMPONENT; else format = GL_LUMINANCE; break; case Bitmap::ELuminanceAlpha: format = GL_LUMINANCE_ALPHA; break; case Bitmap::ERGB: format = GL_RGB; break; case Bitmap::ERGBA: format = GL_RGBA; break; default: Log(EError, "GLTexture::download(): Unknown/unsupported pixel format %i!", (int) bitmap->getPixelFormat()); return; } glPixelStorei(GL_PACK_ALIGNMENT, 1); switch (m_type) { case ETexture2D: glReadPixels(0, 0, bitmap->getWidth(), bitmap->getHeight(), format, dataFormat, bitmap->getUInt8Data()); /* OpenGL associates (0, 0) with the lower left position and the resulting bitmap must thus be vertically flipped. */ bitmap->flipVertically(); break; case ETextureCubeMap: for (int i=0; i<6; ++i) { activateSide(i); bitmap = getBitmap(i); glReadPixels(0, 0, bitmap->getWidth(), bitmap->getHeight(), format, dataFormat, bitmap->getUInt8Data()); bitmap->flipVertically(); } break; default: Log(EError, "download(): Unsupported texture type!"); } releaseTarget(); }
/** * Resets all pixels in this image to 0. * * @code * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image * i.clear(); * @endcode */ void MicroBitImage::clear() { memclr(getBitmap(), getSize()); }
/** * Equality operation. * * Called when one MicroBitImage is tested to be equal to another using the '==' operator. * * @param i The MicroBitImage to test ourselves against. * * @return true if this MicroBitImage is identical to the one supplied, false otherwise. * * @code * MicroBitDisplay display; * MicroBitImage i(); * MicroBitImage i1(); * * if(i == i1) //will be true * display.scroll("true"); * @endcode */ bool MicroBitImage::operator== (const MicroBitImage& i) { if (ptr == i.ptr) return true; else return (ptr->width == i.ptr->width && ptr->height == i.ptr->height && (memcmp(getBitmap(), i.ptr->data, getSize())==0)); }
BITMAP* Resource::getBitmap(const std::string &filename) { return getBitmap(filename, makecol(255, 255, 255)); }
__unused JNIEXPORT void JNICALL Java_com_picsart_studio_gifencoder_GifInfoHandle_bindSurface(JNIEnv *env, jclass __unused handleClass, jlong gifInfo, jobject jsurface, jlongArray savedState, jboolean isOpaque) { GifInfo *info = (GifInfo *) (intptr_t) gifInfo; if (info->surfaceDescriptor == NULL) { info->surfaceDescriptor = malloc(sizeof(SurfaceDescriptor)); if (!initSurfaceDescriptor(info->surfaceDescriptor, env)) { free(info->surfaceDescriptor); info->surfaceDescriptor = NULL; return; } } POLL_TYPE eftd_ctr; int pollResult; while (1) { pollResult = poll(&info->surfaceDescriptor->eventPollFd, 1, 0); if (pollResult == 0) break; else if (pollResult > 0) { if (read(info->surfaceDescriptor->eventPollFd.fd, &eftd_ctr, POLL_TYPE_SIZE) != POLL_TYPE_SIZE) { throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Read on flushing failed"); return; } } else { throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Poll on flushing failed"); return; } } const int32_t windowFormat = isOpaque == JNI_TRUE ? WINDOW_FORMAT_RGBX_8888 : WINDOW_FORMAT_RGBA_8888; info->isOpaque = isOpaque; struct ANativeWindow *window = ANativeWindow_fromSurface(env, jsurface); if (ANativeWindow_setBuffersGeometry(window, (int32_t) info->gifFilePtr->SWidth, (int32_t) info->gifFilePtr->SHeight, windowFormat) != 0) { ANativeWindow_release(window); throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Buffers geometry setting failed"); return; } struct ANativeWindow_Buffer buffer = {.bits =NULL}; void *oldBufferBits; if (ANativeWindow_lock(window, &buffer, NULL) != 0) { ANativeWindow_release(window); throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Window lock failed"); return; } const size_t bufferSize = buffer.stride * buffer.height * sizeof(argb); info->stride = buffer.stride; long invalidationDelayMillis; if (info->surfaceDescriptor->surfaceBackupPtr) { memcpy(buffer.bits, info->surfaceDescriptor->surfaceBackupPtr, bufferSize); invalidationDelayMillis = 0; info->surfaceDescriptor->renderHelper = 1; info->surfaceDescriptor->slurpHelper = 0; } else { if (savedState != NULL){ invalidationDelayMillis = restoreSavedState(info, env, savedState, buffer.bits); if (invalidationDelayMillis <0) invalidationDelayMillis =0; } else invalidationDelayMillis = 0; info->surfaceDescriptor->renderHelper = 0; info->surfaceDescriptor->slurpHelper = 1; } info->lastFrameRemainder = -1; ANativeWindow_unlockAndPost(window); if (info->loopCount != 0 && info->currentLoop == info->loopCount) { ANativeWindow_release(window); pollResult = poll(&info->surfaceDescriptor->eventPollFd, 1, -1); if (pollResult < 0) { throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "animation end poll failed"); } return; } pthread_t thread; if (pthread_create(&thread, NULL, slurp, info) != 0) { ANativeWindow_release(window); throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "pthread_create failed"); return; } while (1) { pollResult = poll(&info->surfaceDescriptor->eventPollFd, 1, (int) invalidationDelayMillis); long renderingStartTime = getRealTime(); if (pollResult < 0) { throwException(env, ILLEGAL_STATE_EXCEPTION_ERRNO, "Poll failed"); break; } else if (pollResult > 0) { if (info->surfaceDescriptor->surfaceBackupPtr == NULL) { info->surfaceDescriptor->surfaceBackupPtr = malloc(bufferSize); if (info->surfaceDescriptor->surfaceBackupPtr == NULL) { throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); break; } } memcpy(info->surfaceDescriptor->surfaceBackupPtr, buffer.bits, bufferSize); break; } oldBufferBits = buffer.bits; THROW_AND_BREAK_ON_NONZERO_RESULT(ANativeWindow_lock(window, &buffer, NULL), "Window lock failed"); if (info->currentIndex == 0) prepareCanvas(buffer.bits, info); else memcpy(buffer.bits, oldBufferBits, bufferSize); pthread_mutex_lock(&info->surfaceDescriptor->renderMutex); while (info->surfaceDescriptor->renderHelper == 0) { pthread_cond_wait(&info->surfaceDescriptor->renderCond, &info->surfaceDescriptor->renderMutex); } info->surfaceDescriptor->renderHelper = 0; pthread_mutex_unlock(&info->surfaceDescriptor->renderMutex); const uint_fast32_t frameDuration = getBitmap(buffer.bits, info); pthread_mutex_lock(&info->surfaceDescriptor->slurpMutex); info->surfaceDescriptor->slurpHelper = 1; pthread_cond_signal(&info->surfaceDescriptor->slurpCond); pthread_mutex_unlock(&info->surfaceDescriptor->slurpMutex); ANativeWindow_unlockAndPost(window); invalidationDelayMillis = calculateInvalidationDelay(info, renderingStartTime, frameDuration); if (info->lastFrameRemainder >= 0) { invalidationDelayMillis = info->lastFrameRemainder; info->lastFrameRemainder = -1; } } ANativeWindow_release(window); pthread_mutex_lock(&info->surfaceDescriptor->slurpMutex); info->surfaceDescriptor->slurpHelper = 2; pthread_cond_signal(&info->surfaceDescriptor->slurpCond); pthread_mutex_unlock(&info->surfaceDescriptor->slurpMutex); THROW_ON_NONZERO_RESULT(pthread_join(thread, NULL), "join failed"); }