// Parse a 'FRGM' chunk and any image bearing chunks that immediately follow. // 'fragment_chunk_size' is the previously validated, padded chunk size. static ParseStatus ParseFragment(WebPDemuxer* const dmux, uint32_t fragment_chunk_size) { const int frame_num = 1; // All fragments belong to the 1st (and only) frame. const int is_fragmented = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); const uint32_t frgm_payload_size = fragment_chunk_size - FRGM_CHUNK_SIZE; int added_fragment = 0; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status = NewFrame(mem, FRGM_CHUNK_SIZE, fragment_chunk_size, &frame); if (status != PARSE_OK) return status; frame->is_fragment_ = 1; frame->x_offset_ = 2 * ReadLE24s(mem); frame->y_offset_ = 2 * ReadLE24s(mem); // Store a fragment only if the 'fragments' flag is set and there is some // data available. status = StoreFrame(frame_num, frgm_payload_size, mem, frame); if (status != PARSE_ERROR && is_fragmented && frame->frame_num_ > 0) { added_fragment = AddFrame(dmux, frame); if (!added_fragment) { status = PARSE_ERROR; } else { dmux->num_frames_ = 1; } } if (!added_fragment) free(frame); return status; }
// Parse a 'TILE' chunk and any image bearing chunks that immediately follow. // 'tile_chunk_size' is the previously validated, padded chunk size. static ParseStatus ParseTile(WebPDemuxer* const dmux, uint32_t tile_chunk_size) { const int has_tiles = !!(dmux->feature_flags_ & TILE_FLAG); const uint32_t min_size = tile_chunk_size + CHUNK_HEADER_SIZE; int added_tile = 0; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status = NewFrame(mem, min_size, TILE_CHUNK_SIZE, tile_chunk_size, &frame); if (status != PARSE_OK) return status; frame->is_tile_ = 1; frame->x_offset_ = 2 * GetLE24s(mem); frame->y_offset_ = 2 * GetLE24s(mem); Skip(mem, tile_chunk_size - TILE_CHUNK_SIZE); // skip any trailing data. // Store a (potentially partial) tile only if the tile flag is set // and the tile contains some data. status = StoreFrame(dmux->num_frames_, mem, frame); if (status != PARSE_ERROR && has_tiles && frame->frame_num_ > 0) { // Note num_frames_ is incremented only when all tiles have been consumed. added_tile = AddFrame(dmux, frame); if (!added_tile) status = PARSE_ERROR; } if (!added_tile) free(frame); return status; }
bool YModem::SendFile(const std::string &path, YModem::SPort &out) { if (path.size() == 0 || not out.is_open()) return false; std::fstream firm_str(path.c_str()); if (not firm_str.is_open()) return false; firm_str.seekg(0, firm_str.end); const size_t kFileSize = firm_str.tellg(); firm_str.seekg(0, firm_str.beg); // ожидание запроса WaitForResponse(out, Packet::kRequest); Packet::Sequence seq(&out); // инициализация соединения char buf[24]; snprintf(buf, 24, "%u", (unsigned)kFileSize); const std::string kMsgs[] = {path, buf}; SendInitialPkt(seq, kMsgs, 2); if (not IsResponse(out, Packet::kRequest)) { firm_str.close(); return false; } // передача файла Array frame(NewFrame()); size_t was_send = 0; size_t last_percent = 0; do { firm_str.sync(); firm_str.read((char*)frame.get(), kFrameSize); const size_t kWasRead = firm_str.gcount(); if (kWasRead != kFrameSize) { memset(frame.get() + kWasRead, 0, kFrameSize - kWasRead); } seq.Send(Packet(Packet::kSTX, frame.get(), kFrameSize)); was_send += kWasRead; if (not IsResponse(out, Packet::kACK)) { std::cout << "\t ! Ошибка передачи данных" << std::endl; break; } const size_t kPercent = was_send * 100 / kFileSize; if (kPercent > last_percent) { ShowPercentage("\t * Прогресс", kPercent); last_percent = kPercent; } } while (was_send < kFileSize); std::cout << std::endl; seq.Send(Packet(Packet::kEOT)); IsResponse(out, Packet::kACK); seq.Send(Packet(Packet::kEOT)); IsResponse(out, Packet::kACK); IsResponse(out, Packet::kRequest); SendClosingPkt(seq); firm_str.close(); return true; }
int main(void) { uint32_t i = 0; RCC_GetClocksFreq( &RCC_Clocks ); ConfigureLED(); LED_OFF; // SysTick end of count event each 10ms SysTick_Config( RCC_Clocks.HCLK_Frequency / 100); float fv = RCC_Clocks.HCLK_Frequency / 1000000.0f; // We can use printf to print back through the debugging interface, but that's slow and // it also takes up a bunch of space. No printf = no space wasted in printf. // printf( "Operating at %.3fMHz\n", fv ); InitColorChord(); Configure_PA0(); InitMP45DT02(); InitSPI2812(); int this_samp = 0; int wf = 0; while(1) { if( this_samp != last_samp_pos ) { LED_OFF; //Use led on the board to show us how much CPU we're using. (You can also probe PB15) PushSample32( sampbuff[this_samp]/2 ); //Can't put in full volume. this_samp = (this_samp+1)%CIRCBUFSIZE; wf++; if( wf == 128 ) { NewFrame(); wf = 0; } LED_ON; } LED_ON; //Take up a little more time to make sure we don't miss this. } }
bool YModem::SendInitialPkt(Packet::Sequence &seq, const std::string *msg, size_t amount) { if (msg == 0 || amount == 0) return false; Array frame(NewFrame()); size_t total = 0; for (size_t msg_i = 0; msg_i < amount; msg_i++) { size_t i = 0; const std::string &kMsg = msg[msg_i]; for (; i < kMsg.size(); i++) { frame.get()[i] = kMsg[i]; } total += i; frame.get()[total] = 0; total++; } return (seq.Send(Packet(Packet::kSTX, frame.get(), kFrameSize)) && IsResponse(*seq.get_port(), Packet::kACK)); }
// Parse a 'ANMF' chunk and any image bearing chunks that immediately follow. // 'frame_chunk_size' is the previously validated, padded chunk size. static ParseStatus ParseAnimationFrame( WebPDemuxer* const dmux, uint32_t frame_chunk_size) { const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE; int added_frame = 0; int bits; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status = NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame); if (status != PARSE_OK) return status; frame->x_offset_ = 2 * ReadLE24s(mem); frame->y_offset_ = 2 * ReadLE24s(mem); frame->width_ = 1 + ReadLE24s(mem); frame->height_ = 1 + ReadLE24s(mem); frame->duration_ = ReadLE24s(mem); bits = ReadByte(mem); frame->dispose_method_ = (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND; if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) { free(frame); return PARSE_ERROR; } // Store a frame only if the animation flag is set there is some data for // this frame is available. status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame); if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) { added_frame = AddFrame(dmux, frame); if (added_frame) { ++dmux->num_frames_; } else { status = PARSE_ERROR; } } if (!added_frame) free(frame); return status; }
// Parse a 'FRM ' chunk and any image bearing chunks that immediately follow. // 'frame_chunk_size' is the previously validated, padded chunk size. static ParseStatus ParseFrame( WebPDemuxer* const dmux, uint32_t frame_chunk_size) { const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); const uint32_t min_size = frame_chunk_size + CHUNK_HEADER_SIZE; int added_frame = 0; MemBuffer* const mem = &dmux->mem_; Frame* frame; ParseStatus status = NewFrame(mem, min_size, FRAME_CHUNK_SIZE, frame_chunk_size, &frame); if (status != PARSE_OK) return status; frame->x_offset_ = 2 * GetLE24s(mem); frame->y_offset_ = 2 * GetLE24s(mem); frame->width_ = 1 + GetLE24s(mem); frame->height_ = 1 + GetLE24s(mem); frame->duration_ = 1 + GetLE24s(mem); Skip(mem, frame_chunk_size - FRAME_CHUNK_SIZE); // skip any trailing data. if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) { return PARSE_ERROR; } // Store a (potentially partial) frame only if the animation flag is set // and there is some data in 'frame'. status = StoreFrame(dmux->num_frames_ + 1, mem, frame); if (status != PARSE_ERROR && has_frames && frame->frame_num_ > 0) { added_frame = AddFrame(dmux, frame); if (added_frame) { ++dmux->num_frames_; } else { status = PARSE_ERROR; } } if (!added_frame) free(frame); return status; }
bool YModem::SendClosingPkt(Packet::Sequence &seq) { seq.Reset(); Array frame(NewFrame()); return (seq.Send(Packet(Packet::kSTX, frame.get(), kFrameSize)) && IsResponse(*seq.get_port(), Packet::kACK)); }