void AsyncLogging::LoggingThreadFuncCallBack() { std::unique_ptr<SyncLogging> syncLogging(new SyncLogging); while (true) { // if there are no log msg in the sync queue, this thread will pending atomaticlly // so, no need to delay manually here std::unique_lock<std::mutex> lk(bufferFullMutex_); if (logSyncQueue_.Empty()) { while (bufferFullCond_.wait_for(lk, std::chrono::seconds(3)) == std::cv_status::timeout) { if (currentBuffer_.Length() != 0) { std::unique_lock<std::mutex> lk(mutex_); syncLogging->Append(currentBuffer_.GetBufferData(), currentBuffer_.Length()); syncLogging->Flush(); currentBuffer_.Clear(); } } } LogBufferType tmpBuffer(logSyncQueue_.Take()); syncLogging->Append(tmpBuffer.GetBufferData(), tmpBuffer.Length()); } }
Stream* Stream::Deserialize(bool decompress) { Stream* value = new Stream(); unsigned int length = ReadDword(); StreamBuffer tmpBuffer(length, 0); ReadData(tmpBuffer); value->WriteData(tmpBuffer); value->Rewind(); if (decompress) value->Inflate(); return value; }
bool z3ResEx::fsRle( TMemoryStream &src, TMemoryStream &dst, bool isMSF ) { unsigned int msfSizeFlag; unsigned int expectedSize, len; unsigned char *pData( src.Data() ), *pDataEnd( pData + src.Size() ); if( isMSF ) { // Read the expected size from data msfSizeFlag = src.ReadUInt(); pData += 4; } if( !( z3Rle::decodeSize( pData, expectedSize, len ) ) ) { dst.Close(); //printf("ERROR: Problems decoding RLE buffer size\n"); return false; } if( isMSF && !( msfSizeFlag == expectedSize ) ) { dst.Close(); //printf("ERROR: Unexpected MSF buffer size\n"); return false; } // Skip the length of the expected size pData += len; vector<unsigned char> tmpBuffer(expectedSize); unsigned int tmpOffset( 0 ); while( tmpOffset < expectedSize ) { if (!(z3Rle::decodeInstruction(pData, len, pDataEnd, &tmpBuffer[0], tmpOffset))) { //printf("ERROR: Problems decoding RLE buffer\n"); return false; } pData += len; } dst.Write(&tmpBuffer[0], expectedSize); return true; }
void PeperoniDevice::run() { if (m_handle == NULL) return; qDebug() << "[Peperoni] input thread started correctly"; while(m_running == true) { int r = -1; QByteArray tmpBuffer(512, 0); /* Choose write method based on firmware version. One has to unplug and then re-plug the dongle in apple for bulk write to work, so disable it for apple, since control msg should work for all. */ #if !defined(__APPLE__) && !defined(Q_OS_MAC) if (m_firmwareVersion < PEPERONI_FW_NEW_BULK_SUPPORT) { #endif r = usb_control_msg(m_handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PEPERONI_RX_MEM_REQUEST, // We are WRITING DMX data 1, // Blocking does not work on all firmware versions -> don't block 0, // Start at DMX address 0 tmpBuffer.data(), // The DMX universe data tmpBuffer.size(), // Size of DMX universe 100); // Timeout (ms) if (r < 0) qWarning() << "PeperoniDevice" << name(m_line) << "failed control_msg:" << usb_strerror(); for (int i = 0; i < 512; i++) { if (tmpBuffer.at(i) != m_dmxInputBuffer.at(i)) emit valueChanged(UINT_MAX, m_line, i, tmpBuffer.at(i)); m_dmxInputBuffer[i] = tmpBuffer.at(i); } #if !defined(__APPLE__) && !defined(Q_OS_MAC) } else { //TODO } #endif } }
bool z3ResEx::z3Decrypt ( TMemoryStream &src, TMemoryStream &dst, unsigned char *key, unsigned int keylen ) { StringSource keyStr( key, keylen, true ); AutoSeededRandomPool rng; ECIES<ECP>::Decryptor ellipticalEnc( keyStr ); vector<unsigned char> tmpBuffer(src.Size()); DecodingResult dr = ellipticalEnc.Decrypt( rng, src.Data(), src.Size(), &tmpBuffer[0] ); if( dr.isValidCoding && dr.messageLength > 0 ) { dst.Write(&tmpBuffer[0], dr.messageLength); return true; } return false; }
bool SkBlurMask::Blur(SkMask* dst, const SkMask& src, SkScalar radius, Style style, Quality quality, SkIPoint* margin) { if (src.fFormat != SkMask::kA8_Format) { return false; } // Force high quality off for small radii (performance) if (radius < SkIntToScalar(3)) { quality = kLow_Quality; } // highQuality: use three box blur passes as a cheap way // to approximate a Gaussian blur int passCount = (kHigh_Quality == quality) ? 3 : 1; SkScalar passRadius = (kHigh_Quality == quality) ? SkScalarMul( radius, kBlurRadiusFudgeFactor): radius; int rx = SkScalarCeil(passRadius); int outerWeight = 255 - SkScalarRound((SkIntToScalar(rx) - passRadius) * 255); SkASSERT(rx >= 0); SkASSERT((unsigned)outerWeight <= 255); if (rx <= 0) { return false; } int ry = rx; // only do square blur for now int padx = passCount * rx; int pady = passCount * ry; if (margin) { margin->set(padx, pady); } dst->fBounds.set(src.fBounds.fLeft - padx, src.fBounds.fTop - pady, src.fBounds.fRight + padx, src.fBounds.fBottom + pady); dst->fRowBytes = dst->fBounds.width(); dst->fFormat = SkMask::kA8_Format; dst->fImage = NULL; if (src.fImage) { size_t dstSize = dst->computeImageSize(); if (0 == dstSize) { return false; // too big to allocate, abort } int sw = src.fBounds.width(); int sh = src.fBounds.height(); const uint8_t* sp = src.fImage; uint8_t* dp = SkMask::AllocImage(dstSize); SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp); // build the blurry destination SkAutoTMalloc<uint8_t> tmpBuffer(dstSize); uint8_t* tp = tmpBuffer.get(); int w = sw, h = sh; if (outerWeight == 255) { int loRadius, hiRadius; get_adjusted_radii(passRadius, &loRadius, &hiRadius); if (kHigh_Quality == quality) { // Do three X blurs, with a transpose on the final one. w = boxBlur(sp, src.fRowBytes, tp, loRadius, hiRadius, w, h, false); w = boxBlur(tp, w, dp, hiRadius, loRadius, w, h, false); w = boxBlur(dp, w, tp, hiRadius, hiRadius, w, h, true); // Do three Y blurs, with a transpose on the final one. h = boxBlur(tp, h, dp, loRadius, hiRadius, h, w, false); h = boxBlur(dp, h, tp, hiRadius, loRadius, h, w, false); h = boxBlur(tp, h, dp, hiRadius, hiRadius, h, w, true); } else { w = boxBlur(sp, src.fRowBytes, tp, rx, rx, w, h, true); h = boxBlur(tp, h, dp, ry, ry, h, w, true); } } else { if (kHigh_Quality == quality) { // Do three X blurs, with a transpose on the final one. w = boxBlurInterp(sp, src.fRowBytes, tp, rx, w, h, false, outerWeight); w = boxBlurInterp(tp, w, dp, rx, w, h, false, outerWeight); w = boxBlurInterp(dp, w, tp, rx, w, h, true, outerWeight); // Do three Y blurs, with a transpose on the final one. h = boxBlurInterp(tp, h, dp, ry, h, w, false, outerWeight); h = boxBlurInterp(dp, h, tp, ry, h, w, false, outerWeight); h = boxBlurInterp(tp, h, dp, ry, h, w, true, outerWeight); } else { w = boxBlurInterp(sp, src.fRowBytes, tp, rx, w, h, true, outerWeight); h = boxBlurInterp(tp, h, dp, ry, h, w, true, outerWeight); } } dst->fImage = dp; // if need be, alloc the "real" dst (same size as src) and copy/merge // the blur into it (applying the src) if (style == kInner_Style) { // now we allocate the "real" dst, mirror the size of src size_t srcSize = src.computeImageSize(); if (0 == srcSize) { return false; // too big to allocate, abort } dst->fImage = SkMask::AllocImage(srcSize); merge_src_with_blur(dst->fImage, src.fRowBytes, sp, src.fRowBytes, dp + passCount * (rx + ry * dst->fRowBytes), dst->fRowBytes, sw, sh); SkMask::FreeImage(dp); } else if (style != kNormal_Style) { clamp_with_orig(dp + passCount * (rx + ry * dst->fRowBytes), dst->fRowBytes, sp, src.fRowBytes, sw, sh, style); } (void)autoCall.detach(); } if (style == kInner_Style) { dst->fBounds = src.fBounds; // restore trimmed bounds dst->fRowBytes = src.fRowBytes; } return true; }
void PeperoniDevice::run() { if (m_handle == NULL) return; qDebug() << "[Peperoni] input thread started correctly"; while(m_running == true) { QByteArray tmpBuffer(512, 0); /* Choose write method based on firmware version. One has to unplug and then re-plug the dongle in apple for bulk write to work, so disable it for apple, since control msg should work for all. */ #if !defined(__APPLE__) && !defined(Q_OS_MAC) if (1 || m_firmwareVersion < PEPERONI_FW_NEW_BULK_SUPPORT) { #endif unsigned short rxslots; unsigned char rxstartcode; unsigned int block; // read memory blocking if firmware is >= 0x0500 if (m_firmwareVersion >= PEPERONI_FW_NEW_BULK_SUPPORT) { block = 1; } else { block = 0; // if we don't block sleep for 10ms usleep(10000); } { int r = -1; QMutexLocker lock(&m_ioMutex); r = usb_control_msg(m_handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PEPERONI_RX_MEM_REQUEST, // We are WRITING DMX data block, // Blocking does not work on all firmware versions -> don't block 0, // Start at DMX address 0 tmpBuffer.data(), // The DMX universe data tmpBuffer.size(), // Size of DMX universe 100); // Timeout (ms) if (r < 0) { qWarning() << "PeperoniDevice" << name(m_baseLine) << "failed control_msg:" << usb_strerror(); r = usb_clear_halt(m_handle, PEPERONI_BULK_IN_ENDPOINT); if (r < 0) qWarning() << "PeperoniDevice" << name(m_baseLine) << "is unable to reset bulk IN endpoint."; } else { /* read received startcode */ r = usb_control_msg(m_handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PEPERONI_RX_STARTCODE, 0, 0, (char *)&rxstartcode, sizeof(rxstartcode), 10); if (r < 0) qWarning() << "PeperoniDevice" << name(m_baseLine) << "failed to read receiver startcode:" << usb_strerror(); else { /* read number of received slots */ r = usb_control_msg(m_handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PEPERONI_RX_SLOTS, 0, 0, (char *)&rxslots, sizeof(rxslots), 10); if (r < 0) qWarning() << "PeperoniDevice" << name(m_baseLine) << "failed to read receiver slot counter:" << usb_strerror(); else { if (rxslots > m_dmxInputBuffer.size()) { rxslots = m_dmxInputBuffer.size(); qWarning() << "PeperoniDevice" << name(m_baseLine) << "input frame too long, truncated"; } //qDebug() << "[Peperoni] input frame has startcode" << rxstartcode << "and is" << rxslots << "slots long"; /* only accept DMX512 data */ if (rxstartcode == 0) { for (int i = 0; i < rxslots; i++) { if (tmpBuffer.at(i) != m_dmxInputBuffer.at(i)) { emit valueChanged(UINT_MAX, m_baseLine, i, tmpBuffer.at(i)); m_dmxInputBuffer[i] = tmpBuffer.at(i); } } } } } } } #if !defined(__APPLE__) && !defined(Q_OS_MAC) } else { //TODO } #endif } }
bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, SkScalar sigma, SkBlurStyle style, SkBlurQuality quality, SkIPoint* margin, bool force_quality) { if (src.fFormat != SkMask::kA8_Format) { return false; } SkIPoint border; #ifdef SK_SUPPORT_LEGACY_MASK_BLUR auto get_adjusted_radii = [](SkScalar passRadius, int *loRadius, int *hiRadius) { *loRadius = *hiRadius = SkScalarCeilToInt(passRadius); if (SkIntToScalar(*hiRadius) - passRadius > 0.5f) { *loRadius = *hiRadius - 1; } }; // Force high quality off for small radii (performance) if (!force_quality && sigma <= SkIntToScalar(2)) { quality = kLow_SkBlurQuality; } SkScalar passRadius; if (kHigh_SkBlurQuality == quality) { // For the high quality path the 3 pass box blur kernel width is // 6*rad+1 while the full Gaussian width is 6*sigma. passRadius = sigma - (1 / 6.0f); } else { // For the low quality path we only attempt to cover 3*sigma of the // Gaussian blur area (1.5*sigma on each side). The single pass box // blur's kernel size is 2*rad+1. passRadius = 1.5f * sigma - 0.5f; } // highQuality: use three box blur passes as a cheap way // to approximate a Gaussian blur int passCount = (kHigh_SkBlurQuality == quality) ? 3 : 1; int rx = SkScalarCeilToInt(passRadius); int outerWeight = 255 - SkScalarRoundToInt((SkIntToScalar(rx) - passRadius) * 255); SkASSERT(rx >= 0); SkASSERT((unsigned)outerWeight <= 255); if (rx <= 0) { return false; } int ry = rx; // only do square blur for now int padx = passCount * rx; int pady = passCount * ry; border = {padx, pady}; dst->fBounds.set(src.fBounds.fLeft - padx, src.fBounds.fTop - pady, src.fBounds.fRight + padx, src.fBounds.fBottom + pady); dst->fRowBytes = dst->fBounds.width(); dst->fFormat = SkMask::kA8_Format; dst->fImage = nullptr; if (src.fImage) { size_t dstSize = dst->computeImageSize(); if (0 == dstSize) { return false; // too big to allocate, abort } int sw = src.fBounds.width(); int sh = src.fBounds.height(); const uint8_t* sp = src.fImage; uint8_t* dp = SkMask::AllocImage(dstSize); SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp); // build the blurry destination SkAutoTMalloc<uint8_t> tmpBuffer(dstSize); uint8_t* tp = tmpBuffer.get(); int w = sw, h = sh; if (outerWeight == 255) { int loRadius, hiRadius; get_adjusted_radii(passRadius, &loRadius, &hiRadius); if (kHigh_SkBlurQuality == quality) { // Do three X blurs, with a transpose on the final one. w = boxBlur<false>(sp, src.fRowBytes, tp, loRadius, hiRadius, w, h); w = boxBlur<false>(tp, w, dp, hiRadius, loRadius, w, h); w = boxBlur<true>(dp, w, tp, hiRadius, hiRadius, w, h); // Do three Y blurs, with a transpose on the final one. h = boxBlur<false>(tp, h, dp, loRadius, hiRadius, h, w); h = boxBlur<false>(dp, h, tp, hiRadius, loRadius, h, w); h = boxBlur<true>(tp, h, dp, hiRadius, hiRadius, h, w); } else { w = boxBlur<true>(sp, src.fRowBytes, tp, rx, rx, w, h); h = boxBlur<true>(tp, h, dp, ry, ry, h, w); } } else { if (kHigh_SkBlurQuality == quality) { // Do three X blurs, with a transpose on the final one. w = boxBlurInterp<false>(sp, src.fRowBytes, tp, rx, w, h, outerWeight); w = boxBlurInterp<false>(tp, w, dp, rx, w, h, outerWeight); w = boxBlurInterp<true>(dp, w, tp, rx, w, h, outerWeight); // Do three Y blurs, with a transpose on the final one. h = boxBlurInterp<false>(tp, h, dp, ry, h, w, outerWeight); h = boxBlurInterp<false>(dp, h, tp, ry, h, w, outerWeight); h = boxBlurInterp<true>(tp, h, dp, ry, h, w, outerWeight); } else { w = boxBlurInterp<true>(sp, src.fRowBytes, tp, rx, w, h, outerWeight); h = boxBlurInterp<true>(tp, h, dp, ry, h, w, outerWeight); } } dst->fImage = autoCall.release(); } #else SkMaskBlurFilter blurFilter{sigma, sigma}; border = blurFilter.blur(src, dst); #endif // SK_SUPPORT_LEGACY_MASK_BLUR if (src.fImage != nullptr) { // if need be, alloc the "real" dst (same size as src) and copy/merge // the blur into it (applying the src) if (style == kInner_SkBlurStyle) { // now we allocate the "real" dst, mirror the size of src size_t srcSize = src.computeImageSize(); if (0 == srcSize) { return false; // too big to allocate, abort } auto blur = dst->fImage; dst->fImage = SkMask::AllocImage(srcSize); auto blurStart = &blur[border.x() + border.y() * dst->fRowBytes]; merge_src_with_blur(dst->fImage, src.fRowBytes, src.fImage, src.fRowBytes, blurStart, dst->fRowBytes, src.fBounds.width(), src.fBounds.height()); SkMask::FreeImage(blur); } else if (style != kNormal_SkBlurStyle) { auto dstStart = &dst->fImage[border.x() + border.y() * dst->fRowBytes]; clamp_with_orig(dstStart, dst->fRowBytes, src.fImage, src.fRowBytes, src.fBounds.width(), src.fBounds.height(), style); } } if (style == kInner_SkBlurStyle) { dst->fBounds = src.fBounds; // restore trimmed bounds dst->fRowBytes = src.fRowBytes; } if (margin != nullptr) { *margin = border; } return true; }
bool SkBlurMask::Blur(SkMask* dst, const SkMask& src, SkScalar radius, Style style, Quality quality, SkIPoint* margin) { if (src.fFormat != SkMask::kA8_Format) { return false; } // Force high quality off for small radii (performance) if (radius < SkIntToScalar(3)) quality = kLow_Quality; // highQuality: use three box blur passes as a cheap way to approximate a Gaussian blur int passCount = (quality == kHigh_Quality) ? 3 : 1; SkScalar passRadius = SkScalarDiv(radius, SkScalarSqrt(SkIntToScalar(passCount))); int rx = SkScalarCeil(passRadius); int outer_weight = 255 - SkScalarRound((SkIntToScalar(rx) - passRadius) * 255); SkASSERT(rx >= 0); SkASSERT((unsigned)outer_weight <= 255); if (rx <= 0) { return false; } int ry = rx; // only do square blur for now int padx = passCount * rx; int pady = passCount * ry; if (margin) { margin->set(padx, pady); } dst->fBounds.set(src.fBounds.fLeft - padx, src.fBounds.fTop - pady, src.fBounds.fRight + padx, src.fBounds.fBottom + pady); dst->fRowBytes = dst->fBounds.width(); dst->fFormat = SkMask::kA8_Format; dst->fImage = NULL; if (src.fImage) { size_t dstSize = dst->computeImageSize(); if (0 == dstSize) { return false; // too big to allocate, abort } int sw = src.fBounds.width(); int sh = src.fBounds.height(); const uint8_t* sp = src.fImage; uint8_t* dp = SkMask::AllocImage(dstSize); SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp); // build the blurry destination { const size_t storageW = sw + 2 * (passCount - 1) * rx + 1; const size_t storageH = sh + 2 * (passCount - 1) * ry + 1; SkAutoTMalloc<uint32_t> storage(storageW * storageH); uint32_t* sumBuffer = storage.get(); //pass1: sp is source, dp is destination build_sum_buffer(sumBuffer, sw, sh, sp, src.fRowBytes); if (outer_weight == 255) { apply_kernel(dp, rx, ry, sumBuffer, sw, sh); } else { apply_kernel_interp(dp, rx, ry, sumBuffer, sw, sh, outer_weight); } if (quality == kHigh_Quality) { //pass2: dp is source, tmpBuffer is destination int tmp_sw = sw + 2 * rx; int tmp_sh = sh + 2 * ry; SkAutoTMalloc<uint8_t> tmpBuffer(dstSize); build_sum_buffer(sumBuffer, tmp_sw, tmp_sh, dp, tmp_sw); if (outer_weight == 255) apply_kernel(tmpBuffer.get(), rx, ry, sumBuffer, tmp_sw, tmp_sh); else apply_kernel_interp(tmpBuffer.get(), rx, ry, sumBuffer, tmp_sw, tmp_sh, outer_weight); //pass3: tmpBuffer is source, dp is destination tmp_sw += 2 * rx; tmp_sh += 2 * ry; build_sum_buffer(sumBuffer, tmp_sw, tmp_sh, tmpBuffer.get(), tmp_sw); if (outer_weight == 255) apply_kernel(dp, rx, ry, sumBuffer, tmp_sw, tmp_sh); else apply_kernel_interp(dp, rx, ry, sumBuffer, tmp_sw, tmp_sh, outer_weight); } } dst->fImage = dp; // if need be, alloc the "real" dst (same size as src) and copy/merge // the blur into it (applying the src) if (style == kInner_Style) { // now we allocate the "real" dst, mirror the size of src size_t srcSize = src.computeImageSize(); if (0 == srcSize) { return false; // too big to allocate, abort } dst->fImage = SkMask::AllocImage(srcSize); merge_src_with_blur(dst->fImage, src.fRowBytes, sp, src.fRowBytes, dp + passCount * (rx + ry * dst->fRowBytes), dst->fRowBytes, sw, sh); SkMask::FreeImage(dp); } else if (style != kNormal_Style) { clamp_with_orig(dp + passCount * (rx + ry * dst->fRowBytes), dst->fRowBytes, sp, src.fRowBytes, sw, sh, style); } (void)autoCall.detach(); } if (style == kInner_Style) { dst->fBounds = src.fBounds; // restore trimmed bounds dst->fRowBytes = src.fRowBytes; } return true; }
//------------------------------------------------------------------------------ //! void Image::createTexture() { if( _bitmap.isNull() ) return; RCP<Bitmap> bmp = _bitmap; // No support for 3 channels. if( bmp->numChannels() == 3 ) { bmp = BitmapManipulator::addAlpha( *bmp, 1.0f ); } uint width = bmp->dimension().x; uint height = bmp->dimension().y; uint depth = bmp->dimension().z; // Currently force power-of-2 size. uint p2_width = CGM::nextPow2( width ); uint p2_height = CGM::nextPow2( height ); // Convert to texture format. Gfx::TextureFormat fmt; Gfx::TextureChannels ch; toTexture( bmp, fmt, ch ); // Create texture. if( _texture.isNull() || !suitable( *_texture, *bmp, p2_width, p2_height, depth, fmt, ch ) ) { switch( bmp->dimType() ) { case Bitmap::DIM_2D: _texture = Core::gfx()->create2DTexture( p2_width, p2_height, fmt, ch, Gfx::TEX_FLAGS_MIPMAPPED ); break; case Bitmap::DIM_CUBEMAP: _texture = Core::gfx()->createCubeTexture( p2_width, fmt, ch, Gfx::TEX_FLAGS_MIPMAPPED ); break; case Bitmap::DIM_2D_ARRAY: //_texture = Core::gfx()->create2DArrayTexture( p2_width, p2_height, depth, fmt, ch, Gfx::TEX_FLAGS_MIPMAPPED ); break; case Bitmap::DIM_3D: _texture = Core::gfx()->create3DTexture( p2_width, p2_height, depth, fmt, ch, Gfx::TEX_FLAGS_MIPMAPPED ); break; } } // Temporary code to clear around texture. if( width < p2_width || height < p2_height ) { size_t tmpSize = CGM::max( width, height ) * bmp->pixelSize(); Vector<uchar> tmpBuffer( tmpSize, 0 ); if( height < p2_height && height != _texture->definedWidth() ) Core::gfx()->setData( _texture, 0, 0, height, width, 1, tmpBuffer.data() ); if( width < p2_width && width != _texture->definedHeight() ) Core::gfx()->setData( _texture, 0, width, 0, 1, height, tmpBuffer.data() ); } _texture->definedRegionX().reset(); _texture->definedRegionY().reset(); switch( bmp->dimType() ) { case Bitmap::DIM_2D: Core::gfx()->setData( _texture, 0, 0, 0, width, height, bmp->pixels() ); break; case Bitmap::DIM_CUBEMAP: Core::gfx()->setData( _texture, 0, Gfx::TEX_SLICE_NEG_X, bmp->pixels(0) ); Core::gfx()->setData( _texture, 0, Gfx::TEX_SLICE_POS_X, bmp->pixels(1) ); Core::gfx()->setData( _texture, 0, Gfx::TEX_SLICE_NEG_Y, bmp->pixels(2) ); Core::gfx()->setData( _texture, 0, Gfx::TEX_SLICE_POS_Y, bmp->pixels(3) ); Core::gfx()->setData( _texture, 0, Gfx::TEX_SLICE_NEG_Z, bmp->pixels(4) ); Core::gfx()->setData( _texture, 0, Gfx::TEX_SLICE_POS_Z, bmp->pixels(5) ); break; case Bitmap::DIM_2D_ARRAY: for( uint s = 0; s < depth; ++s ) { Core::gfx()->setData( _texture, 0, s, 0, 0, width, height, bmp->pixels(s) ); } break; case Bitmap::DIM_3D: Core::gfx()->setData( _texture, 0, 0, 0, 0, width, height, depth, bmp->pixels() ); break; } Core::gfx()->generateMipmaps( _texture ); // Should we delete the image? _needUpdate = false; }
int cpr_load (FILE *pfile) { const int CPR_HEADER_SIZE = 12; const int CPR_CHUNK_ID_SIZE = 4; const int CPR_CHUNK_HEADER_SIZE = 8; cpr_eject(); int rc = cartridge_init(); if (rc != 0) { return rc; } std::unique_ptr<byte> tmpBuffer(new byte[CARTRIDGE_MAX_SIZE]); byte *pbTmpBuffer = tmpBuffer.get(); // Check RIFF header if(fread(pbTmpBuffer, CPR_HEADER_SIZE, 1, pfile) != 1) { // read RIFF header LOG("Cartridge file less than " << CPR_HEADER_SIZE << " bytes long !"); return ERR_CPR_INVALID; } if (memcmp(pbTmpBuffer, "RIFF", 4) != 0) { // RIFF file LOG("Cartridge file is not a RIFF file"); return ERR_CPR_INVALID; } if (memcmp(pbTmpBuffer + 8, "AMS!", 4) != 0) { // CPR file LOG("Cartridge file is not a CPR file"); return ERR_CPR_INVALID; } uint32_t totalSize = extractChunkSize(pbTmpBuffer); LOG("CPR size: " << totalSize) // Extract all chunks uint32_t offset = CPR_HEADER_SIZE; uint32_t cartridgeOffset = 0; while(offset < totalSize) { if(fread(pbTmpBuffer, CPR_CHUNK_HEADER_SIZE, 1, pfile) != 1) { // read chunk header LOG("Failed reading chunk header"); return ERR_CPR_INVALID; } offset += CPR_CHUNK_HEADER_SIZE; byte chunkId[CPR_CHUNK_ID_SIZE+1]; memcpy(chunkId, pbTmpBuffer, CPR_CHUNK_ID_SIZE); chunkId[CPR_CHUNK_ID_SIZE] = '\0'; uint32_t chunkSize = extractChunkSize(pbTmpBuffer); LOG("Chunk '" << chunkId << "' at offset " << offset << " of size " << chunkSize); // Normal chunk size is 16kB // If smaller, it must be filled with 0 up to this limit // If bigger, what is after must be ignored uint32_t chunkKept = std::min(chunkSize, CARTRIDGE_PAGE_SIZE); // If chunk size is not even, there's a pad byte at the end of it if (chunkKept % 2 != 0) { chunkKept++; } // A chunk can be empty (observed on some CPR files) if(chunkKept > 0) { if(fread(&pbCartridgeImage[cartridgeOffset], chunkKept, 1, pfile) != 1) { // read chunk content LOG("Failed reading chunk content"); return ERR_CPR_INVALID; } if(chunkKept < CARTRIDGE_PAGE_SIZE) { // TODO: use the chunkId to identify the cartridge page to set (cbXX with XX between 00 and 31) // This would require intializing the whole to 0 before instead of filling what remains at the end // Not sure if there are some CPR with unordered pages but this seems to be allowed in theory memset(&pbCartridgeImage[cartridgeOffset+chunkKept], 0, CARTRIDGE_PAGE_SIZE-chunkKept); } else if(chunkKept < chunkSize) { LOG("This chunk is bigger than the max allowed size !!!"); if(fread(pbTmpBuffer, chunkSize-chunkKept, 1, pfile) != 1) { // read excessive chunk content LOG("Failed reading chunk content"); return ERR_CPR_INVALID; } } cartridgeOffset += CARTRIDGE_PAGE_SIZE; offset += chunkSize; } } LOG("Final offset: " << offset); LOG("Final cartridge offset: " << cartridgeOffset); memset(&pbCartridgeImage[cartridgeOffset], 0, CARTRIDGE_MAX_SIZE-cartridgeOffset); pbROMlo = &pbCartridgeImage[0]; return 0; }
Animation::Animation(const CC_show& show, NotifyStatus notifyStatus, NotifyErrorList notifyErrorList) : numpts(show.GetNumPoints()), pts(numpts), curr_cmds(numpts), curr_sheetnum(0), mCollisionAction(NULL) { // the variables are persistant through the entire compile process. AnimationVariables variablesStates; for (auto curr_sheet = show.GetSheetBegin(); curr_sheet != show.GetSheetEnd(); ++curr_sheet) { if (!curr_sheet->IsInAnimation()) continue; // Now parse continuity AnimateCompile comp(show, variablesStates); std::vector<std::vector<std::shared_ptr<AnimateCommand> > > theCommands(numpts); for (auto& current_symbol : k_symbols) { if (curr_sheet->ContinuityInUse(current_symbol)) { auto& current_continuity = curr_sheet->GetContinuityBySymbol(current_symbol); std::string tmpBuffer(current_continuity.GetText()); yyinputbuffer = tmpBuffer.c_str(); if (notifyStatus) { std::string message("Compiling \""); message += curr_sheet->GetName().substr(0,32); message += ("\" "); message += GetNameForSymbol(current_symbol).substr(0,32); message += ("..."); notifyStatus(message); } // parse out the error if (parsecontinuity() != 0) { // Supply a generic parse error ContToken dummy; comp.RegisterError(ANIMERR_SYNTAX, &dummy); } for (unsigned j = 0; j < numpts; j++) { if (curr_sheet->GetPoint(j).GetSymbol() == current_symbol) { theCommands[j] = comp.Compile(curr_sheet, j, current_symbol, ParsedContinuity); } } while (ParsedContinuity) { ContProcedure* curr_proc = ParsedContinuity->next; delete ParsedContinuity; ParsedContinuity = curr_proc; } } } // Handle points that don't have continuity (shouldn't happen) if (notifyStatus) { std::string message("Compiling \""); message += curr_sheet->GetName().substr(0,32); message += ("\"..."); notifyStatus(message); } for (unsigned j = 0; j < numpts; j++) { if (theCommands[j].empty()) { theCommands[j] = comp.Compile(curr_sheet, j, MAX_NUM_SYMBOLS, NULL); } } if (!comp.Okay() && notifyErrorList) { std::string message("Errors for \""); message += curr_sheet->GetName().substr(0,32); message += ("\""); if (notifyErrorList(comp.GetErrorMarkers(), std::distance(show.GetSheetBegin(), curr_sheet), message)) { break; } } std::vector<AnimatePoint> thePoints(numpts); for (unsigned i = 0; i < numpts; i++) { thePoints.at(i) = curr_sheet->GetPosition(i); } AnimateSheet new_sheet(thePoints, theCommands, curr_sheet->GetName(), curr_sheet->GetBeats()); sheets.push_back(new_sheet); } }