void open_wav(char *wav) { TCHANINFO *inf; int i; struct t_wave *wavinf; FILE *snd; i=find_free_channel(); if (i==-1) return; last_channel=i; inf=chaninfo+i; snd=fopen(wav,"rb"); if (snd==NULL) { printf("Soubor %s neexistuje.\n",wav); return; } if (find_chunk(snd,WAV_FMT)==-1) { printf("Soubor %s ma poskozenou hlavicku\n",wav); fclose(snd); return; } wavinf=(struct t_wave *)malloc(get_chunk_size(snd)); if (wavinf==NULL) { puts("Nedostatek pamˆti."); return; } read_chunk(snd,wavinf); if (wavinf->wav_mode!=1) { printf("Tento program podporuje pouze WAVy typu 1 (%s)\n",wav); free(wavinf); fclose(snd); return; } inf->chans=wavinf->chans; inf->bit8=wavinf->freq*wavinf->chans==wavinf->bps; inf->repstart=-1; inf->id=-1; inf->left.volume=32768; inf->right.volume=32768; inf->left.vls=0; inf->right.vls=0; free(wavinf); if (find_chunk(snd,WAV_DATA)==0) { printf("Soubor %s je poskozen\n",wav); fclose(snd); return; } inf->size=get_chunk_size(snd); fseek(snd,4,SEEK_CUR); inf->snd=snd; }
// binary search to find chunk for this instr uint32_t find_chunk(uint64_t instr, uint32_t c1, uint32_t c2) { assert (c1 <= c2); if (c1 == c2) return c1; uint32_t mid = (c1 + c2) / 2; // if we ask for instr that is before every instr in log or after every one, // return first / last chunk if (instr < thePandalog->dir.instr[c1]) return c1; if (instr > thePandalog->dir.instr[c2]) return c2; if (thePandalog->dir.instr[c1] <= instr && instr <= thePandalog->dir.instr[mid]) { return find_chunk(instr, c1, mid); } assert (thePandalog->dir.instr[mid] <= instr && instr <= thePandalog->dir.instr[c2]); return find_chunk(instr, mid, c2); }
void wav_reader_c::parse_file() { int chunk_idx; if (m_in->read(&m_wheader.riff, sizeof(m_wheader.riff)) != sizeof(m_wheader.riff)) throw mtx::input::header_parsing_x(); scan_chunks(); if ((chunk_idx = find_chunk("fmt ")) == -1) throw mtx::input::header_parsing_x(); m_in->setFilePointer(m_chunks[chunk_idx].pos, seek_beginning); try { if (m_in->read(&m_wheader.format, sizeof(m_wheader.format)) != sizeof(m_wheader.format)) throw false; if (static_cast<uint64_t>(m_chunks[chunk_idx].len) >= sizeof(alWAVEFORMATEXTENSIBLE)) { alWAVEFORMATEXTENSIBLE format; if (m_in->read(&format, sizeof(format)) != sizeof(format)) throw false; memcpy(&m_wheader.common, &format, sizeof(m_wheader.common)); m_format_tag = get_uint16_le(&m_wheader.common.wFormatTag); if (0xfffe == m_format_tag) m_format_tag = get_uint32_le(&format.extension.guid.data1); } else if (m_in->read(&m_wheader.common, sizeof(m_wheader.common)) != sizeof(m_wheader.common)) throw false; else m_format_tag = get_uint16_le(&m_wheader.common.wFormatTag); } catch (...) { throw mtx::input::header_parsing_x(); } if ((m_cur_data_chunk_idx = find_chunk("data", 0, false)) == -1) throw mtx::input::header_parsing_x(); if (debugging_c::requested("wav_reader|wav_reader_headers")) dump_headers(); m_in->setFilePointer(m_chunks[m_cur_data_chunk_idx].pos + sizeof(struct chunk_struct), seek_beginning); m_remaining_bytes_in_current_data_chunk = m_chunks[m_cur_data_chunk_idx].len; }
void chunk_registry::mark (void* ptr) { auto header = find_chunk (ptr); assert (header && "Must be a valid ptr"); header->set_mark (ptr); }
bool chunk_registry::is_marked (void* ptr) { auto header = find_chunk (ptr); assert (header && "Must be a valid ptr"); return header->is_marked (ptr); }
void ensure_chunks(Chunk *chunks, int *chunk_count, int p, int q, int force) { int count = *chunk_count; for (int i = 0; i < count; i++) { Chunk *chunk = chunks + i; if (chunk_distance(chunk, p, q) >= DELETE_CHUNK_RADIUS) { map_free(&chunk->map); glDeleteBuffers(1, &chunk->position_buffer); glDeleteBuffers(1, &chunk->normal_buffer); glDeleteBuffers(1, &chunk->uv_buffer); Chunk *other = chunks + (--count); memcpy(chunk, other, sizeof(Chunk)); } } int n = CREATE_CHUNK_RADIUS; for (int i = -n; i <= n; i++) { for (int j = -n; j <= n; j++) { int a = p + i; int b = q + j; if (!find_chunk(chunks, count, a, b)) { make_chunk(chunks + count, a, b); count++; if (!force) { *chunk_count = count; return; } } } } *chunk_count = count; }
file_status_e wav_reader_c::read(generic_packetizer_c *, bool) { if (!m_demuxer) return FILE_STATUS_DONE; int64_t requested_bytes = std::min(m_remaining_bytes_in_current_data_chunk, m_demuxer->get_preferred_input_size()); unsigned char *buffer = m_demuxer->get_buffer(); int64_t num_read; num_read = m_in->read(buffer, requested_bytes); if (0 >= num_read) return flush_packetizers(); m_demuxer->process(num_read); m_remaining_bytes_in_current_data_chunk -= num_read; if (!m_remaining_bytes_in_current_data_chunk) { m_cur_data_chunk_idx = find_chunk("data", m_cur_data_chunk_idx + 1, false); if (-1 == m_cur_data_chunk_idx) return flush_packetizers(); m_in->setFilePointer(m_chunks[m_cur_data_chunk_idx].pos + sizeof(struct chunk_struct), seek_beginning); m_remaining_bytes_in_current_data_chunk = m_chunks[m_cur_data_chunk_idx].len; } return FILE_STATUS_MOREDATA; }
// another binary search to find first index into current chunk for this instr uint32_t find_ind(uint64_t instr, uint32_t i1, uint32_t i2) { assert (i1 <= i2); if (i1 == i2) return i1; uint32_t mid = (i1 + i2) / 2; PandalogChunk *chunk = &(thePandalog->chunk); if (instr < chunk->entry[i1]->instr) { // just means first instr in log is after what we want return i1; } if (instr > chunk->entry[i2]->instr) { // just means we asked for instr that is after last instr in log return i2; } if (chunk->entry[i1]->instr <= instr && instr <= chunk->entry[mid]->instr) { return find_chunk(instr, i1, mid); } assert (chunk->entry[mid]->instr <= instr && instr <= chunk->entry[i2]->instr); return find_chunk(instr, mid, i2); }
CStreamReader *CStreamReader::open_chunk (const u32 &chunk_id) { BOOL compressed; u32 size = find_chunk(chunk_id,&compressed); if (!size) return (0); R_ASSERT2 (!compressed,"cannot use CStreamReader on compressed chunks"); CStreamReader *result = xr_new<CStreamReader>(); result->construct (file_mapping_handle(),m_start_offset + tell(),size,m_archive_size,m_window_size); return (result); }
void _set_block( Chunk *chunks, int chunk_count, int p, int q, int x, int y, int z, int w) { Chunk *chunk = find_chunk(chunks, chunk_count, p, q); if (chunk) { Map *map = &chunk->map; map_set(map, x, y, z, w); update_chunk(chunk); } db_insert_block(p, q, x, y, z, w); }
int get_block( Chunk *chunks, int chunk_count, int x, int y, int z) { int p = chunked(x); int q = chunked(z); Chunk *chunk = find_chunk(chunks, chunk_count, p, q); if (chunk) { Map *map = &chunk->map; return map_get(map, x, y, z); } return 0; }
void _set_block( Chunk *chunks, int chunk_count, int p, int q, int x, int y, int z, int w) { Chunk *chunk = find_chunk(chunks, chunk_count, p, q); if (chunk) { Map *map = &chunk->map; if (map_get(map, x, y, z) != w) { map_set(map, x, y, z, w); chunk->dirty = 1; } } db_insert_block(p, q, x, y, z, w); }
void ensure_chunks( Chunk *chunks, int *chunk_count, float x, float y, float z, int force) { int p = chunked(x); int q = chunked(z); int count = *chunk_count; for (int i = 0; i < count; i++) { Chunk *chunk = chunks + i; if (chunk_distance(chunk, p, q) >= DELETE_CHUNK_RADIUS) { map_free(&chunk->map); glDeleteBuffers(1, &chunk->position_buffer); glDeleteBuffers(1, &chunk->normal_buffer); glDeleteBuffers(1, &chunk->uv_buffer); Chunk *other = chunks + (--count); memcpy(chunk, other, sizeof(Chunk)); } } int rings = force ? 1 : CREATE_CHUNK_RADIUS; int generated = 0; for (int ring = 0; ring <= rings; ring++) { for (int dp = -ring; dp <= ring; dp++) { for (int dq = -ring; dq <= ring; dq++) { if (ring != MAX(ABS(dp), ABS(dq))) { continue; } if (!force && generated && ring > 1) { continue; } int a = p + dp; int b = q + dq; Chunk *chunk = find_chunk(chunks, count, a, b); if (chunk) { if (chunk->dirty) { gen_chunk_buffers(chunk); generated++; } } else { if (count < MAX_CHUNKS) { create_chunk(chunks + count, a, b); generated++; count++; } } } } } *chunk_count = count; }
//--------------------------------------------------- // base stream IReader* IReader::open_chunk(u32 ID) { BOOL bCompressed; u32 dwSize = find_chunk(ID,&bCompressed); if (dwSize!=0) { if (bCompressed) { BYTE* dest; unsigned dest_sz; _decompressLZ(&dest,&dest_sz,pointer(),dwSize); return new CTempReader(dest, dest_sz, tell()+dwSize); } else { return new IReader(pointer(), dwSize, tell()+dwSize); } } else return 0; };
model decode_omdl(const path_t& path , const void* buffer, size_t size , const layout_t& desired_layout , const allocator& subsets_alloc , const allocator& mesh_alloc , const allocator& temp_alloc) { if (!is_omdl(buffer, size)) return model(); auto hdr = (const file_header*)buffer; auto chk = hdr->find_chunk(omdl_info_signature); if (!chk) oThrow(std::errc::invalid_argument, "invalid omdl: no info section"); auto info = *chk->data<info_t>(); model mdl(info, subsets_alloc, mesh_alloc); chk = chk->next(); if (chk->fourcc != omdl_subsets_signature) oThrow(std::errc::invalid_argument, "invalid omdl: no subsets section"); memcpy(mdl.subsets(), chk->data<subset_t>(), chk->uncompressed_bytes); chk = chk->next(); if (chk->fourcc != omdl_indices_signature) oThrow(std::errc::invalid_argument, "invalid omdl: no indices section"); memcpy(mdl.indices(), chk->data<uint16_t>(), chk->uncompressed_bytes); const uint32_t nslots = info.num_slots; for (uint32_t slot = 0; slot < nslots; slot++) { chk = chk->next(); if (chk->fourcc != omdl_vertex_slot_signature) oThrow(std::errc::invalid_argument, "invalid omdl: no vertices slot section"); memcpy(mdl.vertices(slot), chk->data<void>(), chk->uncompressed_bytes); } return mdl; }
int highest_block(Chunk *chunks, int chunk_count, float x, float z) { int result = -1; int nx = roundf(x); int nz = roundf(z); int p = floorf(roundf(x) / CHUNK_SIZE); int q = floorf(roundf(z) / CHUNK_SIZE); Chunk *chunk = find_chunk(chunks, chunk_count, p, q); if (chunk) { Map *map = &chunk->map; MAP_FOR_EACH(map, e) { if (is_obstacle(e->w) && e->x == nx && e->z == nz) { result = MAX(result, e->y); } } END_MAP_FOR_EACH; } return result; }
int collide( Chunk *chunks, int chunk_count, int height, float *x, float *y, float *z) { int result = 0; int p = floorf(roundf(*x) / CHUNK_SIZE); int q = floorf(roundf(*z) / CHUNK_SIZE); Chunk *chunk = find_chunk(chunks, chunk_count, p, q); if (!chunk) { return result; } Map *map = &chunk->map; int nx = roundf(*x); int ny = roundf(*y); int nz = roundf(*z); float px = *x - nx; float py = *y - ny; float pz = *z - nz; float pad = 0.25; for (int dy = 0; dy < height; dy++) { if (px < -pad && is_obstacle(map_get(map, nx - 1, ny - dy, nz))) { *x = nx - pad; } if (px > pad && is_obstacle(map_get(map, nx + 1, ny - dy, nz))) { *x = nx + pad; } if (py < -pad && is_obstacle(map_get(map, nx, ny - dy - 1, nz))) { *y = ny - pad; result = 1; } if (py > pad && is_obstacle(map_get(map, nx, ny - dy + 1, nz))) { *y = ny + pad; result = 1; } if (pz < -pad && is_obstacle(map_get(map, nx, ny - dy, nz - 1))) { *z = nz - pad; } if (pz > pad && is_obstacle(map_get(map, nx, ny - dy, nz + 1))) { *z = nz + pad; } } return result; }
void *malloc(size_t size) { if (size == 0 ) return NULL; size_t lenght = word_align(size); struct chunk *c = find_chunk(size); if(c->next==NULL) { if (extend_heap(c,lenght) == 0) return NULL; } else { c->next->free = 0; } return (&c->next->data); }
void pandalog_seek(uint64_t instr) { assert(in_read_mode()); // figure out which chunk this instr in is uint32_t c = find_chunk(instr, 0, thePandalog->dir.max_chunks-1); thePandalog->chunk_num = c; unmarshall_chunk(c); // figure out ind uint32_t ind = find_ind(instr, 0, thePandalog->dir.num_entries[c]-1); if (thePandalog->mode == PL_MODE_READ_BWD) { // need *last* entry with that instr for backward mode uint32_t i; // uint8_t found_entry = 0; for (i=ind; i<thePandalog->dir.num_entries[c]; i++) { Panda__LogEntry *ple = thePandalog->chunk.entry[i]; if (ple->instr != instr || instr > ple->instr) { ind --; break; } } } thePandalog->chunk.ind_entry = ind; }
void ensure_chunks(Chunk *chunks, int *chunk_count, int p, int q, int force) { int count = *chunk_count; for (int i = 0; i < count; i++) { Chunk *chunk = chunks + i; if (chunk_distance(chunk, p, q) >= DELETE_CHUNK_RADIUS) { map_free(&chunk->map); glDeleteBuffers(1, &chunk->position_buffer); glDeleteBuffers(1, &chunk->normal_buffer); glDeleteBuffers(1, &chunk->uv_buffer); Chunk *other = chunks + (--count); memcpy(chunk, other, sizeof(Chunk)); } } int n = force ? 1 : CREATE_CHUNK_RADIUS; for (int i = 0; i <= n; i++) { for (int dp = -n; dp <= n; dp++) { for (int dq = -n; dq <= n; dq++) { int j = MAX(ABS(dp), ABS(dq)); if (i != j) { continue; } int a = p + dp; int b = q + dq; if (!find_chunk(chunks, count, a, b)) { make_chunk(chunks + count, a, b); count++; if (!force) { *chunk_count = count; return; } } } } } *chunk_count = count; }
void mix_buffer(int size) { int chan,i; memset(source,0,size*2); for(chan=0;chan<CHANNELS;chan++) { if (chaninfo[chan].snd!=NULL) { TCHANINFO *inf=chaninfo+chan; for(i=0;i<size;i+=2) { int left,right; if (inf->bit8) { fread(&left,1,1,inf->snd);left=(short)(left*256); left^=0xffff8000; inf->size--; } else { fread(&left,1,2,inf->snd);left=(short)left; inf->size-=2; } if (inf->chans==1) right=left; else if (inf->bit8) { fread(&right,1,1,inf->snd);right=(short)(right*256); right^=0xffff8000; inf->size--; } else { fread(&right,1,2,inf->snd);right=(short)right; inf->size-=2; } left=(int)left*inf->left.volume/(32768); right=(int)right*inf->right.volume/(32768); left=left*glob_volume/256; right=right*glob_volume/256; calc_vls(&inf->left); calc_vls(&inf->right); left+=source[i]; right+=source[i+1]; if (left>32767) left=32767; if (left<-32767) left=-32767; if (right>32767) right=32767; if (right<-32767) right=-32767; source[i]=left; source[i+1]=right; if (inf->size<=0) { if (inf->repstart!=-1) { fseek(inf->snd,0,SEEK_SET); find_chunk(inf->snd,WAV_DATA); inf->size=get_chunk_size(inf->snd); fseek(inf->snd,4,SEEK_CUR); fseek(inf->snd,inf->repstart,SEEK_CUR); inf->size-=inf->repstart; } else { fclose(inf->snd); inf->snd=NULL; break; } } } } } }
/** Prepares "start" RDA packet with channel names determined from the corresponding chunk (or empty) Also converts to little-endian if this machine is big endian @param hdr Points to headerdef_t structure, will be filled, may not be NULL @return created start item, or NULL on error (connection / out of memory) */ rda_buffer_item_t *rda_aux_get_hdr_prep_start(int ft_buffer, headerdef_t *hdr) { rda_buffer_item_t *item = NULL; const ft_chunk_t *chunk; rda_msg_start_t *R; char *str; double *dRes; const void *dResSource; size_t bytesTotal; int i,r,numExtraZeros,sizeOrgNames; message_t req, *resp = NULL; messagedef_t msg_def; req.def = &msg_def; req.buf = NULL; msg_def.version = VERSION; msg_def.command = GET_HDR; msg_def.bufsize = 0; r = clientrequest(ft_buffer, &req, &resp); if (r<0 || resp == NULL || resp->def == NULL) { goto cleanup; } if (resp->def->command != GET_OK || resp->def->bufsize < sizeof(headerdef_t) || resp->buf == NULL) { goto cleanup; } memcpy(hdr, resp->buf, sizeof(headerdef_t)); /* Ok, we have the basic header, now look for proper FT_CHUNK_RESOLUTIONS */ chunk = find_chunk(resp->buf, sizeof(headerdef_t), resp->def->bufsize, FT_CHUNK_RESOLUTIONS); if (chunk != NULL && chunk->def.size == hdr->nchans*sizeof(double)) { dResSource = chunk->data; /* fine - we just need a memcpy later on */ } else { dResSource = NULL; /* no suitable chunk found - set defaults later on */ } /* Now see if we can find channel names */ chunk = find_chunk(resp->buf, sizeof(headerdef_t), resp->def->bufsize, FT_CHUNK_CHANNEL_NAMES); if (chunk != NULL && chunk->def.size >= hdr->nchans) { /* The chunk seems ok - check whether we really have N (0-terminated) strings */ int k,nz = 0; for (k = 0; k<chunk->def.size && nz<=hdr->nchans; k++) { if (chunk->data[k] == 0) nz++; } /* Okay, either k is at the end and we have nz<=N, or we have reached N=nz before the end of the chunk. In both cases, it's safe to transmit the first 'k' bytes and add (N-nz) trailing zeros */ numExtraZeros = hdr->nchans - nz; sizeOrgNames = k; } else { sizeOrgNames = 0; numExtraZeros = hdr->nchans; } bytesTotal = sizeof(rda_msg_start_t) + hdr->nchans*(sizeof(double)) + sizeOrgNames + numExtraZeros; item = rda_aux_alloc_item(bytesTotal); if (item == NULL) goto cleanup; R = (rda_msg_start_t *) item->data; memcpy(R->hdr.guid, _rda_guid, sizeof(_rda_guid)); R->hdr.nSize = bytesTotal; R->hdr.nType = RDA_START_MSG; R->nChannels = hdr->nchans; R->dSamplingInterval = 1.0e6/(double) hdr->fsample; /* should be in microseconds */ if (_i_am_big_endian_) { /* take care of hdr.nSize, hdr.nType, nChannels */ ft_swap32(3, &(R->hdr.nSize)); ft_swap64(1, &(R->dSamplingInterval)); } /* R+1 points to first byte after header info */ dRes = (double *) ((void *)(R+1)); if (dResSource == NULL) { /* Fill with resolution = 1.0 -- we have nothing better */ for (i=0;i<hdr->nchans;i++) dRes[i]=1.0; } else { memcpy(dRes, dResSource, hdr->nchans * sizeof(double)); } /* swap byte order if necessary */ if (_i_am_big_endian_) { ft_swap64(hdr->nchans, dRes); } /* Let 'str' point to first byte after the resolution values */ str = (char *) ((void *)(dRes + hdr->nchans)); if (sizeOrgNames > 0) { memcpy(str, chunk->data, sizeOrgNames); } for (i=0;i<numExtraZeros;i++) str[sizeOrgNames + i] = 0; /* done */ cleanup: if (resp) { if (resp->def) free(resp->def); if (resp->buf) free(resp->buf); free(resp); } return item; }
static z_blorb_map *fizmo_blorb_init(z_file *blorb_file) { z_blorb_map *result_wrapper; fizmo_blorb_map *result; fizmo_blorb *blorb; int resource_chunk_size; char buf[5]; int nof_resources, nof_loops, blorb_index, resource_number; if (find_chunk("RIdx", blorb_file) == -1) { fsi->closefile(blorb_file); return NULL; } if (read_chunk_length(blorb_file) == -1) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_FUNCTION_CALL_P0S_RETURNED_ERROR_CODE_P1D, -0x0101, "read_chunk_length", errno); result = fizmo_malloc(sizeof(fizmo_blorb_map)); result->blorb_file = blorb_file; result_wrapper = fizmo_malloc(sizeof(z_blorb_map)); result_wrapper->blorb_map_implementation = result; resource_chunk_size = get_last_chunk_length(); nof_resources = (resource_chunk_size - 4) / 12; // Skip next number of resources. if ((fsi->setfilepos(result->blorb_file, 4, SEEK_CUR)) != 0) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_FUNCTION_CALL_P0S_RETURNED_ERROR_CODE_P1D, -0x0101, "setfilepos", errno); TRACE_LOG("Number of resources in blorb file: %d.\n", nof_resources); // Count number of images and sounds. result->blorbs = fizmo_malloc(sizeof(fizmo_blorb*) * (nof_resources+1)); buf[4] = '\0'; blorb_index = 0; while (nof_resources > 0) { blorb = fizmo_malloc(sizeof(fizmo_blorb)); if (fsi->readchars(buf, 4, result->blorb_file) != 4) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_FUNCTION_CALL_P0S_ABORTED_DUE_TO_ERROR, -0x0106, "readchars"); TRACE_LOG("Type descriptor: %s\n", buf); if (strcmp(buf, "Pict") == 0) blorb->type = Z_BLORB_TYPE_PICT; else if (strcmp(buf, "Snd ") == 0) blorb->type = Z_BLORB_TYPE_SOUND; else if (strcmp(buf, "Exec") == 0) blorb->type = Z_BLORB_TYPE_EXEC; else // Unknown resource. i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_UNKNOWN_ERROR_CASE, -1); blorb->resource_number = read_four_byte_number(result->blorb_file); blorb->offset = read_four_byte_number(result->blorb_file) + 8; blorb->v3_number_of_loops = -1; result->blorbs[blorb_index++] = blorb; nof_resources--; } result->blorbs[blorb_index] = NULL; if (find_chunk("Fspc", result->blorb_file) == 0) { if ((fsi->setfilepos(result->blorb_file, 4, SEEK_CUR)) != 0) i18n_translate_and_exit( libfizmo_module_name, i18n_libfizmo_FUNCTION_CALL_P0S_RETURNED_ERROR_CODE_P1D, -0x0101, "setfilepos", errno); result->frontispiece_image_no = read_four_byte_number(result->blorb_file); } else result->frontispiece_image_no = -1; if (ver < 5) { if (find_chunk("Loop", result->blorb_file) == 0) { nof_resources = read_four_byte_number(result->blorb_file) / 8; TRACE_LOG("Number of loop entries: %d.\n", nof_resources); while (nof_resources > 0) { resource_number = read_four_byte_number(result->blorb_file); nof_loops = read_four_byte_number(result->blorb_file); TRACE_LOG("Trying to find resource #%d.\n", resource_number); if ((blorb = fizmo_get_blorb( result_wrapper, Z_BLORB_TYPE_SOUND, resource_number)) != NULL) { TRACE_LOG("Resource found, setting nof_loops to %d.\n", nof_loops); blorb->v3_number_of_loops = nof_loops; } nof_resources--; } } } return result_wrapper; }
// Besides passing in type, also pass some necessary fields as parameters // Other fields in the parameters can be arbitrary values // To make a WHOHAS packet, pass in the request and *packet_count // To make a IHAVE packet, pass in a WHOHAS packet as packet_in // To make a Get packet, pass in p_chunk // struct packet* make_packet(unsigned char packet_type, struct Chunk* p_chunk, char* data, int data_size, int seq_number, int ack_number, struct packet* packet_in, int* packet_count, struct Request* request){ unsigned char i = 0; int j = 0; int unfinished_chunk_count = 0; struct packet* packet = NULL; switch(packet_type){ case WHOHAS: for(i=0;i<request->chunk_number;i++){ // TODO: here may need to change add more state to chunks if(request->chunks[i].state == NOT_STARTED){ unfinished_chunk_count++; } } if(unfinished_chunk_count%CHUNK_PER_PACKET==0){ *packet_count = unfinished_chunk_count/CHUNK_PER_PACKET; } else{ *packet_count = unfinished_chunk_count/CHUNK_PER_PACKET + 1; } struct packet* packets = (struct packet*)malloc(sizeof(struct packet)* (*packet_count)); memset(packets, 0, sizeof(struct packet)* (*packet_count)); if(unfinished_chunk_count==0){ free_packets(packets, *packet_count); packets = NULL; } int current_chunk_index = 0; for(j=0;j<(*packet_count);j++){ unsigned char chunk_count = CHUNK_PER_PACKET; if(*packet_count <= j+1){ chunk_count = (unsigned char)(unfinished_chunk_count - j*CHUNK_PER_PACKET); } fill_header(&packets[j].header, WHOHAS, chunk_count*SHA1_HASH_SIZE+HEADER_LENGTH+CHUNK_NUMBER_AND_PADDING_SIZE, 0, 0); *(packets[j].payload) = chunk_count; int k=0; for(k=0;k<chunk_count;k++){ for(; current_chunk_index<request->chunk_number;current_chunk_index++){ if(request->chunks[current_chunk_index].state==NOT_STARTED){ memcpy(packets[j].payload+CHUNK_NUMBER_AND_PADDING_SIZE+k*SHA1_HASH_SIZE,(request->chunks)[current_chunk_index].hash, SHA1_HASH_SIZE); current_chunk_index++; break; } } } } return packets; case IHAVE: packet = (struct packet*)malloc(sizeof(struct packet)); memset(packet, 0, sizeof(struct packet)); unsigned char chunk_count = *((char*)packet_in+16); unsigned char count_ihave = 0; for(i=0;i<chunk_count;i++){ uint8_t* hash = (uint8_t*)((char*)packet_in+16+CHUNK_NUMBER_AND_PADDING_SIZE+i*SHA1_HASH_SIZE); if(find_chunk(hash)>0){ memcpy(packet->payload+CHUNK_NUMBER_AND_PADDING_SIZE+count_ihave*SHA1_HASH_SIZE, hash, SHA1_HASH_SIZE); count_ihave++; } } if(count_ihave==0){ free_packet(packet); packet = NULL; } else{ fill_header(&(packet->header), IHAVE, count_ihave*SHA1_HASH_SIZE+HEADER_LENGTH+CHUNK_NUMBER_AND_PADDING_SIZE, 0, 0); // *(packet->payload) = count_ihave; memcpy(packet->payload, &count_ihave, 1); } break; case GET: packet = (struct packet*)malloc(sizeof(struct packet)); memset(packet, 0, sizeof(struct packet)); fill_header(&packet->header, GET, SHA1_HASH_SIZE+HEADER_LENGTH, 0, 0); memcpy(packet->payload, p_chunk->hash, SHA1_HASH_SIZE); break; case DATA: packet = (struct packet*)malloc(sizeof(struct packet)); memset(packet, 0, sizeof(struct packet)); fill_header(&packet->header, DATA, data_size+HEADER_LENGTH, seq_number, 0); memcpy(packet->payload, data, data_size); break; case ACK: packet = (struct packet*)malloc(sizeof(struct packet)); memset(packet, 0, sizeof(struct packet)); fill_header(&packet->header, ACK, HEADER_LENGTH, 0, ack_number); break; default: printf("Should not happen in make_packet\n"); break; } return packet; }
bool loadWavSampleFromBytes(const float *inData, int len, QuickVec<unsigned char> &outBuffer, int *channels, int *bitsPerSample, int* outSampleRate) { const char* start = (const char*)inData; const char* end = start + len; const char* ptr = start; WAVE_Format wave_format; RIFF_Header riff_header; WAVE_Data wave_data; unsigned char* data; // Read in the first chunk into the struct memcpy(&riff_header, ptr, sizeof(RIFF_Header)); ptr += sizeof(RIFF_Header); //check for RIFF and WAVE tag in memeory if ((riff_header.chunkID[0] != 'R' || riff_header.chunkID[1] != 'I' || riff_header.chunkID[2] != 'F' || riff_header.chunkID[3] != 'F') || (riff_header.format[0] != 'W' || riff_header.format[1] != 'A' || riff_header.format[2] != 'V' || riff_header.format[3] != 'E')) { LOG_SOUND("Invalid RIFF or WAVE Header!\n"); return false; } //Read in the 2nd chunk for the wave info ptr = find_chunk(ptr, end, "fmt "); if (!ptr) { return false; } readStruct(wave_format, ptr); //check for fmt tag in memory if (wave_format.subChunkID[0] != 'f' || wave_format.subChunkID[1] != 'm' || wave_format.subChunkID[2] != 't' || wave_format.subChunkID[3] != ' ') { LOG_SOUND("Invalid Wave Format!\n"); return false; } ptr = find_chunk(ptr, end, "data"); if (!ptr) { return false; } const char* base = readStruct(wave_data, ptr); //check for data tag in memory if (wave_data.subChunkID[0] != 'd' || wave_data.subChunkID[1] != 'a' || wave_data.subChunkID[2] != 't' || wave_data.subChunkID[3] != 'a') { LOG_SOUND("Invalid Wav Data Header!\n"); return false; } //Allocate memory for data //data = new unsigned char[wave_data.subChunk2Size]; // Read in the sound data into the soundData variable size_t size = wave_data.subChunkSize; if (size > (end - base)) { return false; } /*mlChannels = wave_format.numChannels; if (mlChannels == 2) { if (wave_format.bitsPerSample == 8) { mFormat = AL_FORMAT_STEREO8; mlSamples = size / 2; } else //if (wave_format.bitsPerSample == 16) { mlSamples = size / 4; mFormat = AL_FORMAT_STEREO16; } } else //if (mlChannels == 1) { if (wave_format.bitsPerSample == 8) { mlSamples = size; mFormat = AL_FORMAT_MONO8; } else //if (wave_format.bitsPerSample == 16) { mlSamples = size / 2; mFormat = AL_FORMAT_MONO16; } } mlFrequency = wave_format.sampleRate; mfTotalTime = float(mlSamples) / float(mlFrequency);*/ //Store in the outbuffer outBuffer.Set((unsigned char*)base, size); //Now we set the variables that we passed in with the //data from the structs *outSampleRate = (int)wave_format.sampleRate; //The format is worked out by looking at the number of //channels and the bits per sample. *channels = wave_format.numChannels; *bitsPerSample = wave_format.bitsPerSample; //clean up and return true if successful //fclose(f); //delete[] data; return true; }
bool WAV::Decode (Resource *resource, AudioBuffer *audioBuffer) { WAVE_Format wave_format; RIFF_Header riff_header; WAVE_Data wave_data; unsigned char* data; FILE_HANDLE *file = NULL; if (resource->path) { file = lime::fopen (resource->path, "rb"); if (!file) { return false; } int result = lime::fread (&riff_header, sizeof (RIFF_Header), 1, file); if ((riff_header.chunkID[0] != 'R' || riff_header.chunkID[1] != 'I' || riff_header.chunkID[2] != 'F' || riff_header.chunkID[3] != 'F') || (riff_header.format[0] != 'W' || riff_header.format[1] != 'A' || riff_header.format[2] != 'V' || riff_header.format[3] != 'E')) { lime::fclose (file); return false; } long int currentHead = 0; bool foundFormat = false; while (!foundFormat) { currentHead = lime::ftell (file); result = lime::fread (&wave_format, sizeof (WAVE_Format), 1, file); if (result != 1) { LOG_SOUND ("Invalid Wave Format!\n"); lime::fclose (file); return false; } if (wave_format.subChunkID[0] != 'f' || wave_format.subChunkID[1] != 'm' || wave_format.subChunkID[2] != 't' || wave_format.subChunkID[3] != ' ') { lime::fseek (file, wave_format.subChunkSize, SEEK_CUR); } else { foundFormat = true; } } bool foundData = false; while (!foundData) { currentHead = lime::ftell (file); result = lime::fread (&wave_data, sizeof (WAVE_Data), 1, file); if (result != 1) { LOG_SOUND ("Invalid Wav Data Header!\n"); lime::fclose (file); return false; } if (wave_data.subChunkID[0] != 'd' || wave_data.subChunkID[1] != 'a' || wave_data.subChunkID[2] != 't' || wave_data.subChunkID[3] != 'a') { lime::fseek (file, currentHead + sizeof (WAVE_Data) + wave_data.subChunkSize, SEEK_SET); } else { foundData = true; } } audioBuffer->data = new Bytes (wave_data.subChunkSize); audioBuffer->length = wave_data.subChunkSize; if (!lime::fread (audioBuffer->data->Data (), wave_data.subChunkSize, 1, file)) { LOG_SOUND ("error loading WAVE data into struct!\n"); lime::fclose (file); return false; } lime::fclose (file); } else { const char* start = (const char*)resource->data->Data (); const char* end = start + resource->data->Length (); const char* ptr = start; memcpy (&riff_header, ptr, sizeof (RIFF_Header)); ptr += sizeof (RIFF_Header); if ((riff_header.chunkID[0] != 'R' || riff_header.chunkID[1] != 'I' || riff_header.chunkID[2] != 'F' || riff_header.chunkID[3] != 'F') || (riff_header.format[0] != 'W' || riff_header.format[1] != 'A' || riff_header.format[2] != 'V' || riff_header.format[3] != 'E')) { return false; } ptr = find_chunk (ptr, end, "fmt "); if (!ptr) { return false; } readStruct (wave_format, ptr); if (wave_format.subChunkID[0] != 'f' || wave_format.subChunkID[1] != 'm' || wave_format.subChunkID[2] != 't' || wave_format.subChunkID[3] != ' ') { LOG_SOUND ("Invalid Wave Format!\n"); return false; } ptr = find_chunk (ptr, end, "data"); if (!ptr) { return false; } const char* base = readStruct (wave_data, ptr); if (wave_data.subChunkID[0] != 'd' || wave_data.subChunkID[1] != 'a' || wave_data.subChunkID[2] != 't' || wave_data.subChunkID[3] != 'a') { LOG_SOUND ("Invalid Wav Data Header!\n"); return false; } audioBuffer->data->Resize (wave_data.subChunkSize); size_t size = wave_data.subChunkSize; if (size > (end - base)) { return false; } unsigned char* bytes = audioBuffer->data->Data (); memcpy (bytes, base, size); } audioBuffer->sampleRate = (int)wave_format.sampleRate; audioBuffer->channels = wave_format.numChannels; audioBuffer->bitsPerSample = wave_format.bitsPerSample; return true; }
int load_pic(char *name) { FILE *fd = fopen(name, "rb"); Uint32 type; /* Couldn't open */ if (!fd) return 0; type = read_header(fd); /* Not an IFF file */ if (!type) { fclose(fd); return 0; } switch(type) { case PBM: { if (find_chunk(fd, BMHD)) { Uint16 sizex = freadhe16(fd); Uint16 sizey = freadhe16(fd); Uint8 compression; int colors = 256; Uint32 bodylength; /* * Hop over the "hotspot", planes & masking (stencil pictures are * always saved as ILBMs! */ fseek(fd, 6, SEEK_CUR); compression = fread8(fd); fread8(fd); fread8(fd); fread8(fd); /* * That was all we needed of the BMHD, now the CMAP (optional hehe!) */ if (find_chunk(fd, CMAP)) { int count; for (count = 0; count < colors; count++) { sc.red[count] = fread8(fd) >> 2; sc.green[count] = fread8(fd) >> 2; sc.blue[count] = fread8(fd) >> 2; } } /* * Now the BODY chunk, this is important! */ bodylength = find_chunk(fd, BODY); if (bodylength) { sc.sizex = sizex; sc.sizey = sizey; sc.data = malloc(sc.sizex * sc.sizey); if (!sc.data) { fclose(fd); return 0; } if (!compression) { int ycount; for (ycount = 0; ycount < sizey; ycount++) { fread(&sc.data[sc.sizex * ycount], sizex, 1, fd); } } else { int ycount; char *ptr = malloc(bodylength); char *origptr = ptr; if (!ptr) { fclose(fd); return 0; } fread(ptr, bodylength, 1, fd); /* Run-length encoding */ for (ycount = 0; ycount < sizey; ycount++) { int total = 0; while (total < sizex) { signed char decision = *ptr++; if (decision >= 0) { memcpy(&sc.data[sc.sizex * ycount + total], ptr, decision + 1); ptr += decision + 1; total += decision + 1; } if ((decision < 0) && (decision != -128)) { memset(&sc.data[sc.sizex * ycount + total], *ptr++, -decision + 1); total += -decision + 1; } } } free(origptr); } } } } break; case ILBM: { if (find_chunk(fd, BMHD)) { Uint16 sizex = freadhe16(fd); Uint16 sizey = freadhe16(fd); Uint8 compression; Uint8 planes; Uint8 mask; int colors; Uint32 bodylength; /* * Hop over the "hotspot" */ fseek(fd, 4, SEEK_CUR); planes = fread8(fd); mask = fread8(fd); compression = fread8(fd); fread8(fd); fread8(fd); fread8(fd); colors = poweroftwo[planes]; if (mask > 1) mask = 0; /* * That was all we needed of the BMHD, now the CMAP (optional hehe!) */ if (find_chunk(fd, CMAP)) { int count; for (count = 0; count < 256; count++) { sc.red[count] = 0; sc.green[count] = 0; sc.blue[count] = 0; } sc.red[255] = 255; sc.green[255] = 255; sc.blue[255] = 255; for (count = 0; count < colors; count++) { sc.red[count] = fread8(fd) >> 2; sc.green[count] = fread8(fd) >> 2; sc.blue[count] = fread8(fd) >> 2; } } /* * Now the BODY chunk, this is important! */ bodylength = find_chunk(fd, BODY); if (bodylength) { char *ptr; char *origptr; char *unpackedptr; char *workptr; int ycount, plane; int bytes, dbytes; sc.sizex = sizex; sc.sizey = sizey; sc.data = malloc(sc.sizex * sc.sizey); memset(sc.data, 0, sc.sizex * sc.sizey); if (!sc.data) { fclose(fd); return 0; } origptr = malloc(bodylength * 2); ptr = origptr; if (!origptr) { fclose(fd); return 0; } fread(origptr, bodylength, 1, fd); if (compression) { dbytes = sizey * (planes + mask) * ((sizex + 7) / 8); unpackedptr = malloc(dbytes); workptr = unpackedptr; if (!unpackedptr) { fclose(fd); return 0; } bytes = 0; while (bytes < dbytes) { signed char decision = *ptr++; if (decision >= 0) { memcpy(workptr, ptr, decision + 1); workptr += decision + 1; ptr += decision + 1; bytes += decision + 1; } if ((decision < 0) && (decision != -128)) { memset(workptr, *ptr++, -decision + 1); workptr += -decision + 1; bytes += -decision + 1; } } free(origptr); origptr = unpackedptr; ptr = unpackedptr; } for (ycount = 0; ycount < sizey; ycount++) { for (plane = 0; plane < planes; plane++) { int xcount = (sizex + 7) / 8; int xcoord = 0; while (xcount) { if (*ptr & 128) sc.data[sc.sizex * ycount + xcoord + 0] |= poweroftwo[plane]; if (*ptr & 64 ) sc.data[sc.sizex * ycount + xcoord + 1] |= poweroftwo[plane]; if (*ptr & 32 ) sc.data[sc.sizex * ycount + xcoord + 2] |= poweroftwo[plane]; if (*ptr & 16 ) sc.data[sc.sizex * ycount + xcoord + 3] |= poweroftwo[plane]; if (*ptr & 8 ) sc.data[sc.sizex * ycount + xcoord + 4] |= poweroftwo[plane]; if (*ptr & 4 ) sc.data[sc.sizex * ycount + xcoord + 5] |= poweroftwo[plane]; if (*ptr & 2 ) sc.data[sc.sizex * ycount + xcoord + 6] |= poweroftwo[plane]; if (*ptr & 1 ) sc.data[sc.sizex * ycount + xcoord + 7] |= poweroftwo[plane]; ptr++; xcoord += 8; xcount--; } } if (mask) { ptr += (sizex + 7) / 8; } } free(origptr); } } } break; } fclose(fd); return 1; }
int find_chunk_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) { return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, out_chunk_offset, out_chunk_size, 0, 0); }
static int detect_and_add_z_file(char *filename, char *blorb_filename, struct babel_info *babel, struct z_story_list *story_list) { z_file *infile; uint8_t buf[30]; uint32_t val; char serial[7]; int version; uint16_t checksum; uint16_t release; struct babel_story_info *b_info = NULL; char *title; char *author; char *language; char *description; char *ptr, *ptr2; int length; time_t storyfile_timestamp; char *empty_string = ""; struct z_story_list_entry *entry; int chunk_length = -1; struct babel_info *file_babel = NULL; bool file_is_zblorb; char *cwd = NULL; char *abs_filename = NULL; if (filename == NULL) return -1; if (filename[0] != '/') { cwd = fsi->get_cwd(); abs_filename = fizmo_malloc(strlen(cwd) + strlen(filename) + 2); sprintf(abs_filename, "%s/%s", cwd, filename); } else abs_filename = filename; if ((infile = fsi->openfile(abs_filename, FILETYPE_DATA, FILEACCESS_READ)) == NULL) { if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } if ((storyfile_timestamp = fsi->get_last_file_mod_timestamp(infile)) < 0) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } if (fsi->readchars(buf, 30, infile) != 30) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } if (memcmp(buf, "FORM", 4) == 0) { // IFF file. if ( (is_form_type(infile, "IFRS") != true) || (find_chunk("ZCOD", infile) == -1) ) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } file_is_zblorb = true; if (find_chunk("IFmd", infile) == 0) { read_chunk_length(infile); chunk_length = get_last_chunk_length(); file_babel = load_babel_info_from_blorb( infile, chunk_length, abs_filename, storyfile_timestamp); babel = file_babel; } find_chunk("ZCOD", infile); read_chunk_length(infile); length = get_last_chunk_length(); if (fsi->readchars(buf, 30, infile) != 30) { fsi->closefile(infile); if (cwd != NULL) { free(cwd); free(abs_filename); } return -1; } } else { fsi->setfilepos(infile, 0, SEEK_END); length = fsi->getfilepos(infile); file_is_zblorb = false; } fsi->closefile(infile); val = (buf[16] << 24) | (buf[17] << 16) | (buf[18] << 8) | (buf[19]); if ( ((val & 0xbe00f0f0) != 0x3030) || (*buf < 1) || (*buf > 8) ) { if (cwd != NULL) { free(cwd); free(abs_filename); } return -2; } version = *buf; memcpy(serial, buf + 0x12, 6); serial[6] = '\0'; checksum = (buf[0x1c] << 8) | buf[0x1d]; release = (buf[2] << 8) | buf[3]; if ((entry = get_z_story_entry(serial, release, length, story_list)) != NULL) { // We already have the story in our story-list. If we have a raw file // we can just quit if the support-blorbfilename is the same (raw files // don't contain metadata which might have changed). if ( (file_is_zblorb == false) && ( ( (entry->blorbfile == NULL) && (blorb_filename != NULL) ) // || (Don't delete blorb file) // ( (blorb_filename == NULL) && (entry->blorbfile != NULL) ) || ( (entry->blorbfile != NULL) && (blorb_filename != NULL) && (strcmp(blorb_filename, entry->blorbfile) == 0) ) ) ) { if (cwd != NULL) { free(cwd); free(abs_filename); } return -3; } //printf("%ld / %ld\n", storyfile_timestamp, entry->storyfile_timestamp); // In case new file is a zblorb and we have save a raw file, remove the // raw and keep the blorb (so we can get images and sound). We'll also // re-read the file contents if the file has changed (metadata might // have been altered). if ( (strcmp(entry->filetype, filetype_raw) == 0) || (storyfile_timestamp > entry->storyfile_timestamp) ) { remove_entry_from_list(story_list, entry); //printf("%s...\n", abs_filename); } else { if (cwd != NULL) { free(cwd); free(abs_filename); } return -4; } } ptr2 = NULL; if ((b_info = get_babel_story_info( release, serial, checksum, babel, file_is_zblorb)) != NULL) { title = (b_info->title == NULL ? empty_string : b_info->title); author = (b_info->author == NULL ? empty_string : b_info->author); language = (b_info->language == NULL ? empty_string : b_info->language); description = (b_info->description != NULL) ? b_info->description : empty_string; } else { if ((title = strrchr(abs_filename, '/')) == NULL) title = abs_filename; else title++; if ((ptr = strrchr(title, '.')) != NULL) { TRACE_LOG("strdup: %s\n", title); ptr2 = fizmo_strdup(title); ptr = strrchr(ptr2, '.'); if ( ( (strlen(ptr) == 3) && (ptr[1] == 'z') && (isdigit(ptr[2]) != 0) ) || (strcasecmp(ptr, ".dat") == 0) || (strcasecmp(ptr, ".zblorb") == 0) ) *ptr = '\0'; *ptr2 = toupper(*ptr2); title = ptr2; } author = empty_string; language = empty_string; description = empty_string; } add_entry_to_story_list( story_list, title, author, language, description, serial, version, length, checksum, release, abs_filename, file_is_zblorb ? NULL : blorb_filename, file_is_zblorb ? filetype_zblorb : filetype_raw, storyfile_timestamp); if (b_info != NULL) free_babel_story_info(b_info); if (ptr2 != NULL) free(ptr2); if (file_babel != NULL) free_babel_info(file_babel); if (cwd != NULL) { free(cwd); free(abs_filename); } return 0; }