chunk_t read_chunk( psocksxx::iosockstream * socket ) throw() { chunk_t chunk; std::string line; std::vector<std::string> chunk_header; // initialise chunk chunk.size = 0; chunk.extention = ""; chunk.data = ""; // read chunk header read_chunk_header( socket, chunk ); // read chunk data if ( chunk.size > 0 ) { chunk.data = read_data( socket, chunk.size ); } // read \r\n ending for the chunk read_data( socket, 2 ); return chunk; }
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng, unsigned *ret) { unsigned i; struct png_chunk chunk = {0}; if (!read_chunk_header(buf, &chunk)) return false; #if 0 for (i = 0; i < 4; i++) { fprintf(stderr, "chunktype: %c\n", chunk.type[i]); } #endif switch (png_chunk_type(&chunk)) { case PNG_CHUNK_NOOP: default: break; case PNG_CHUNK_ERROR: goto error; case PNG_CHUNK_IHDR: if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend) goto error; if (chunk.size != 13) goto error; if (!png_parse_ihdr(buf, &rpng->ihdr)) goto error; if (!png_process_ihdr(&rpng->ihdr)) goto error; rpng->has_ihdr = true; break; case PNG_CHUNK_PLTE: { unsigned entries = chunk.size / 3; if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat) goto error; if (chunk.size % 3) goto error; if (!png_read_plte_into_buf(buf, rpng->palette, entries)) goto error; rpng->has_plte = true; } break; case PNG_CHUNK_IDAT: if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte))) goto error; if (!png_realloc_idat(&chunk, &rpng->idat_buf)) goto error; buf += 8; for (i = 0; i < chunk.size; i++) rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i]; rpng->idat_buf.size += chunk.size; rpng->has_idat = true; break; case PNG_CHUNK_IEND: if (!(rpng->has_ihdr) || !(rpng->has_idat)) goto error; rpng->has_iend = true; goto error; } *ret = 4 + 4 + chunk.size + 4; return true; error: return false; }
int Cvqa_file::post_open() { int error = read(&m_header, sizeof(t_vqa_header)); // Read header return error ? error : read_chunk_header(); }
static int open_roq(bgav_demuxer_context_t * ctx) { int i; chunk_header_t h; bgav_stream_t * s; uint16_t width = 0, height = 0, framerate; int num_channels = 0; /* We can play RoQ files only from seekable sources */ if(!ctx->input->input->seek_byte) { bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Cannot play Roq files from nonseekable source"); return 0; } /* Skip magic */ bgav_input_skip(ctx->input, 6); if(!bgav_input_read_16_le(ctx->input, &framerate)) return 0; for(i = 0; i < RoQ_CHUNKS_TO_SCAN; i++) { if(!read_chunk_header(ctx->input, &h)) break; switch(h.id) { case RoQ_INFO: if(!bgav_input_read_16_le(ctx->input, &width) || !bgav_input_read_16_le(ctx->input, &height)) return 0; bgav_input_skip(ctx->input, 4); break; case RoQ_QUAD_CODEBOOK: case RoQ_QUAD_VQ: bgav_input_skip(ctx->input, h.size); break; case RoQ_SOUND_MONO: num_channels = 1; bgav_input_skip(ctx->input, h.size); break; case RoQ_SOUND_STEREO: num_channels = 2; bgav_input_skip(ctx->input, h.size); break; default: bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Unknown Roq chunk %04x", h.id); return 0; break; } if(width && height && num_channels) break; } /* Seek back */ bgav_input_seek(ctx->input, 8, SEEK_SET); /* Set up track table */ ctx->tt = bgav_track_table_create(1); /* Set up audio stream */ if(num_channels) { s = bgav_track_add_audio_stream(ctx->tt->cur, ctx->opt); s->stream_id = AUDIO_ID; s->fourcc = BGAV_MK_FOURCC('R','O','Q','A'); s->data.audio.format.num_channels = num_channels; s->data.audio.format.samplerate = RoQ_AUDIO_SAMPLE_RATE; s->data.audio.bits_per_sample = 16; s->data.audio.block_align = num_channels * s->data.audio.bits_per_sample; } if(width && height) { s = bgav_track_add_video_stream(ctx->tt->cur, ctx->opt); s->stream_id = VIDEO_ID; s->fourcc = BGAV_MK_FOURCC('R','O','Q','V'); s->data.video.format.image_width = width; s->data.video.format.image_height = height; s->data.video.format.frame_width = width; s->data.video.format.frame_height = height; s->data.video.format.pixel_width = 1; s->data.video.format.pixel_height = 1; s->data.video.format.timescale = framerate; s->data.video.format.frame_duration = 1; } gavl_metadata_set(&ctx->tt->cur->metadata, GAVL_META_FORMAT, "ID Roq"); ctx->data_start = ctx->input->position; ctx->flags |= BGAV_DEMUXER_HAS_DATA_START; return 1; }
IFusionSoundBuffer * load_sample (IFusionSound *sound, const char *filename) { DirectResult ret; int fd; FSBufferDescription desc; IFusionSoundBuffer *buffer; void *data; fmtChunk fmt; int len; fd = open (filename, O_RDONLY); if (fd < 0) { perror (filename); return NULL; } if (read_file_header (fd)) { close (fd); return NULL; } while (1) { char magic[4]; len = read_chunk_header (fd, magic); if (len <= 0) { fprintf (stderr, "Could not find format chunk!\n"); close (fd); return NULL; } if (magic[0] == 'f' || magic[1] == 'm' || magic[2] == 't') { if (len < sizeof(fmtChunk)) { fprintf (stderr, "Format chunk has invalid size (%d/%zu)!\n", len, sizeof(fmtChunk)); close (fd); return NULL; } if (read (fd, &fmt, sizeof(fmtChunk)) < sizeof(fmtChunk)) { fprintf (stderr, "Could not read format chunk!\n"); close (fd); return NULL; } if (lseek (fd, len - sizeof(fmtChunk), SEEK_CUR) == (off_t) -1) { fprintf (stderr, "Could not seek past chunk!\n"); close (fd); return NULL; } break; } else { if (lseek (fd, len, SEEK_CUR) == (off_t) -1) { fprintf (stderr, "Could not seek past chunk!\n"); close (fd); return NULL; } } } #ifdef WORDS_BIGENDIAN fixup_fmtchunk( &fmt ); #endif if (fmt.encoding != 1) { fprintf (stderr, "Only PCM supported, yet!\n"); close (fd); return NULL; } if (fmt.bitspersample != 16 && fmt.bitspersample != 8) { fprintf (stderr, "Only 16 or 8 bit supported, yet!\n"); close (fd); return NULL; } desc.flags = FSBDF_LENGTH | FSBDF_CHANNELS | FSBDF_SAMPLEFORMAT | FSBDF_SAMPLERATE; desc.channels = fmt.channels; desc.sampleformat = (fmt.bitspersample == 8) ? FSSF_U8 : FSSF_S16; desc.samplerate = fmt.frequency; while (1) { char magic[4]; len = read_chunk_header (fd, magic); if (len <= 0) { fprintf (stderr, "Could not find data chunk!\n"); close (fd); return NULL; } if (magic[0] == 'd' && magic[1] == 'a' && magic[2] == 't' && magic[3] == 'a') { desc.length = len / fmt.blockalign; break; } else { if (lseek (fd, len, SEEK_CUR) == (off_t) -1) { fprintf (stderr, "Could not seek past chunk!\n"); close (fd); return NULL; } } } ret = sound->CreateBuffer (sound, &desc, &buffer); if (ret) { FusionSoundError ("IFusionSound::CreateBuffer", ret); close (fd); return NULL; } buffer->Lock (buffer, &data, 0, 0); if (read (fd, data, len) < len) fprintf (stderr, "Warning: Could not read all data bytes!\n"); #ifdef WORDS_BIGENDIAN if (fmt.bitspersample == 16) fixup_sampledata (data, len); #endif close (fd); buffer->Unlock (buffer); return buffer; }
int unpack(void *input, size_t input_size, void** output) { int chunk_id; int chunk_options; int pos = 0; unsigned long chunk_size; unsigned long chunk_checksum; unsigned long chunk_extra; unsigned char buffer[BLOCK_SIZE]; unsigned long checksum; unsigned long decompressed_size; unsigned long total_extracted; unsigned char* compressed_buffer; unsigned char* decompressed_buffer; unsigned long compressed_bufsize; unsigned long decompressed_bufsize; unsigned char* b_input = (unsigned char*) input; size_t output_size = 0; /* sanity check */ if (input_size < 8) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Data too short"); return -1; } input_size = input_size + sizeof(sixpack_magic); /* not a 6pack archive? */ if(!detect_magic(input, input_size)) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Data not in 6pack format"); return -1; } /* position of first chunk */ pos = 8; /* initialize */ total_extracted = 0; decompressed_size = 0; compressed_buffer = 0; decompressed_buffer = 0; compressed_bufsize = 0; decompressed_bufsize = 0; /* main loop */ for(;;) { /* end of file? */ if(pos > input_size) break; read_chunk_header(input, input_size, &pos, &chunk_id, &chunk_options, &chunk_size, &chunk_checksum, &chunk_extra); if((chunk_id == 1) && (chunk_size > 10) && (chunk_size < BLOCK_SIZE)) { /* file entry */ int c; for (c=0;c<chunk_size;c++) { if (pos < input_size) { buffer[c] = b_input[pos]; pos++; } else { break; } } checksum = update_adler32(1L, buffer, chunk_size); if(checksum != chunk_checksum) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Checksum mismatch. Got %08lX, expected %08lX", checksum, chunk_checksum); return (-1); } decompressed_size = readU32(buffer); total_extracted = 0; } if((chunk_id == 17) && decompressed_size) { unsigned long remaining; /* uncompressed */ switch(chunk_options) { /* stored, simply copy to output */ case 0: /* read one block at at time, write and update checksum */ total_extracted += chunk_size; remaining = chunk_size; checksum = 1L; for(;;) { unsigned long r = (BLOCK_SIZE < remaining) ? BLOCK_SIZE: remaining; int c; for (c=0;c<r;c++) { if (pos<input_size) { buffer[c] = b_input[pos]; pos++; } else{ break; } } size_t bytes_read = c; if(bytes_read == 0) break; output_size = mem_append(output, output_size, buffer, bytes_read); checksum = update_adler32(checksum, buffer, bytes_read); remaining -= bytes_read; } /* verify everything is written correctly */ if(checksum != chunk_checksum) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Checksum mismatch. Got %08lX, expected %08lX", checksum, chunk_checksum); return (-1); } break; /* compressed using FastLZ */ case 1: /* enlarge input buffer if necessary */ if(chunk_size > compressed_bufsize) { compressed_bufsize = chunk_size; efree(compressed_buffer); compressed_buffer = (unsigned char*)emalloc(compressed_bufsize); } /* enlarge output buffer if necessary */ if(chunk_extra > decompressed_bufsize) { decompressed_bufsize = chunk_extra; efree(decompressed_buffer); decompressed_buffer = (unsigned char*)emalloc(decompressed_bufsize); } /* read and check checksum */ int c; for (c=0;c<chunk_size;c++) { if (pos<input_size) { compressed_buffer[c] = b_input[pos]; pos++; } else{ break; } } checksum = update_adler32(1L, compressed_buffer, chunk_size); total_extracted += chunk_extra; /* verify that the chunk data is correct */ if(checksum != chunk_checksum) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Checksum mismatch. Got %08lX, expected %08lX", checksum, chunk_checksum); return (-1); } else { /* decompress and verify */ remaining = fastlz_decompress(compressed_buffer, chunk_size, decompressed_buffer, chunk_extra); if(remaining != chunk_extra) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompression failed. Skipped"); } else output_size = mem_append(output, output_size, decompressed_buffer, chunk_extra); } break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown compression method (%d)\n", chunk_options); break; } } /* position of next chunk */ //pos = pos + 16 + chunk_size; //fseek(in, pos + 16 + chunk_size, SEEK_SET); } /* free allocated stuff */ efree(compressed_buffer); efree(decompressed_buffer); /* so far so good */ return total_extracted; }
static int open_smaf(bgav_demuxer_context_t * ctx) { int done = 0; uint8_t params; chunk_header_t ch; bgav_stream_t * s; smaf_priv_t * priv; priv = calloc(1, sizeof(*priv)); ctx->priv = priv; /* Skip MMMD chunk */ bgav_input_skip(ctx->input, 8); while(!done) { if(!read_chunk_header(ctx->input, &ch)) return 0; // dump_chunk_header(&ch); if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('M','T','R',0)) { bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "MIDI like files not supported"); return 0; } else if((ch.fourcc == BGAV_MK_FOURCC('C','N','T','I')) || (ch.fourcc == BGAV_MK_FOURCC('O','P','D','A'))) bgav_input_skip(ctx->input, ch.size); else if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('A','T','R',0)) done = 1; else { bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Unsupported SMAF chunk (%c%c%c%c)", (ch.fourcc & 0xFF000000) >> 24, (ch.fourcc & 0x00FF0000) >> 16, (ch.fourcc & 0x0000FF00) >> 8, (ch.fourcc & 0x000000FF)); return 0; } } /* Initialize generic things */ ctx->tt = bgav_track_table_create(1); s = bgav_track_add_audio_stream(ctx->tt->cur, ctx->opt); /* Now, get the format */ bgav_input_skip(ctx->input, 1); /* format type */ bgav_input_skip(ctx->input, 1); /* sequence type */ /* (channel << 7) | (format << 4) | rate */ if(!bgav_input_read_data(ctx->input, ¶ms, 1)) return 0; s->data.audio.format.samplerate = mmf_rate(params & 0x0f); s->fourcc = BGAV_MK_FOURCC('S','M','A','F'); s->data.audio.bits_per_sample = 4; s->data.audio.format.num_channels = 1; s->data.audio.bits_per_sample = 4; s->container_bitrate = s->data.audio.bits_per_sample * s->data.audio.format.samplerate; if(s->data.audio.format.samplerate < 0) { bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Invalid samplerate"); return 0; } bgav_input_skip(ctx->input, 1); /* wave base bit */ bgav_input_skip(ctx->input, 1); /* time base d */ bgav_input_skip(ctx->input, 1); /* time base g */ done = 0; while(!done) { if(!read_chunk_header(ctx->input, &ch)) return 0; // dump_chunk_header(&ch); if((ch.fourcc == BGAV_MK_FOURCC('A','t','s','q')) || (ch.fourcc == BGAV_MK_FOURCC('A','s','p','I'))) bgav_input_skip(ctx->input, ch.size); else if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('A','w','a', 0)) done = 1; else { bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Unsupported SMAF chunk (%c%c%c%c)", (ch.fourcc & 0xFF000000) >> 24, (ch.fourcc & 0x00FF0000) >> 16, (ch.fourcc & 0x0000FF00) >> 8, (ch.fourcc & 0x000000FF)); return 0; } } priv->bytes_left = ch.size; gavl_metadata_set(&ctx->tt->cur->metadata, GAVL_META_FORMAT, "SMAF Ringtone"); return 1; }
bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height) { long pos; *data = NULL; *width = 0; *height = 0; bool ret = true; FILE *file = fopen(path, "rb"); if (!file) return false; fseek(file, 0, SEEK_END); long file_len = ftell(file); rewind(file); bool has_ihdr = false; bool has_idat = false; bool has_iend = false; bool has_plte = false; uint8_t *inflate_buf = NULL; size_t inflate_buf_size = 0; z_stream stream = {0}; struct idat_buffer idat_buf = {0}; struct png_ihdr ihdr = {0}; uint32_t palette[256] = {0}; char header[8]; if (fread(header, 1, sizeof(header), file) != sizeof(header)) GOTO_END_ERROR(); if (memcmp(header, png_magic, sizeof(png_magic)) != 0) GOTO_END_ERROR(); // feof() apparently isn't triggered after a seek (IEND). for (pos = ftell(file); pos < file_len && pos >= 0; pos = ftell(file)) { struct png_chunk chunk = {0}; if (!read_chunk_header(file, &chunk)) GOTO_END_ERROR(); switch (png_chunk_type(&chunk)) { case PNG_CHUNK_NOOP: default: if (fseek(file, chunk.size + sizeof(uint32_t), SEEK_CUR) < 0) GOTO_END_ERROR(); break; case PNG_CHUNK_ERROR: GOTO_END_ERROR(); case PNG_CHUNK_IHDR: if (has_ihdr || has_idat || has_iend) GOTO_END_ERROR(); if (!png_parse_ihdr(file, &chunk, &ihdr)) GOTO_END_ERROR(); has_ihdr = true; break; case PNG_CHUNK_PLTE: if (!has_ihdr || has_plte || has_iend || has_idat) GOTO_END_ERROR(); if (chunk.size % 3) GOTO_END_ERROR(); if (!png_read_plte(file, palette, chunk.size / 3)) GOTO_END_ERROR(); has_plte = true; break; case PNG_CHUNK_IDAT: if (!has_ihdr || has_iend || (ihdr.color_type == 3 && !has_plte)) GOTO_END_ERROR(); if (!png_append_idat(file, &chunk, &idat_buf)) GOTO_END_ERROR(); has_idat = true; break; case PNG_CHUNK_IEND: if (!has_ihdr || !has_idat) GOTO_END_ERROR(); if (fseek(file, sizeof(uint32_t), SEEK_CUR) < 0) GOTO_END_ERROR(); has_iend = true; break; } } if (!has_ihdr || !has_idat || !has_iend) GOTO_END_ERROR(); if (inflateInit(&stream) != Z_OK) GOTO_END_ERROR(); png_pass_geom(&ihdr, ihdr.width, ihdr.height, NULL, NULL, &inflate_buf_size); if (ihdr.interlace == 1) // To be sure. inflate_buf_size *= 2; inflate_buf = (uint8_t*)malloc(inflate_buf_size); if (!inflate_buf) GOTO_END_ERROR(); stream.next_in = idat_buf.data; stream.avail_in = idat_buf.size; stream.avail_out = inflate_buf_size; stream.next_out = inflate_buf; if (inflate(&stream, Z_FINISH) != Z_STREAM_END) { inflateEnd(&stream); GOTO_END_ERROR(); } inflateEnd(&stream); *width = ihdr.width; *height = ihdr.height; *data = (uint32_t*)malloc(ihdr.width * ihdr.height * sizeof(uint32_t)); if (!*data) GOTO_END_ERROR(); if (ihdr.interlace == 1) { if (!png_reverse_filter_adam7(*data, &ihdr, inflate_buf, stream.total_out, palette)) GOTO_END_ERROR(); } else if (!png_reverse_filter(*data, &ihdr, inflate_buf, stream.total_out, palette)) GOTO_END_ERROR(); end: if (file) fclose(file); if (!ret) free(*data); free(idat_buf.data); free(inflate_buf); return ret; }
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng) { unsigned i; rpng->chunk.size = 0; rpng->chunk.type[0] = '\0'; if (!read_chunk_header(buf, &rpng->chunk)) return false; #if 0 for (i = 0; i < 4; i++) { fprintf(stderr, "chunktype: %c\n", chunk.type[i]); } #endif switch (png_chunk_type(&rpng->chunk)) { case PNG_CHUNK_NOOP: default: break; case PNG_CHUNK_ERROR: return false; case PNG_CHUNK_IHDR: if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend) return false; if (rpng->chunk.size != 13) return false; if (!png_parse_ihdr(buf, &rpng->ihdr)) return false; rpng->has_ihdr = true; break; case PNG_CHUNK_PLTE: { unsigned entries = rpng->chunk.size / 3; if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat) return false; if (rpng->chunk.size % 3) return false; if (!png_read_plte_into_buf(buf, rpng->palette, entries)) return false; rpng->has_plte = true; } break; case PNG_CHUNK_IDAT: if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == 3 && !(rpng->has_plte))) return false; if (!png_realloc_idat(&rpng->chunk, &rpng->idat_buf)) return false; buf += 8; for (i = 0; i < rpng->chunk.size; i++) rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i]; rpng->idat_buf.size += rpng->chunk.size; rpng->has_idat = true; break; case PNG_CHUNK_IEND: if (!(rpng->has_ihdr) || !(rpng->has_idat)) return false; rpng->has_iend = true; return false; } return true; }
static int open_aiff(bgav_demuxer_context_t * ctx) { chunk_header_t ch; comm_chunk_t comm; uint32_t fourcc; bgav_stream_t * s = NULL; aiff_priv_t * priv; int keep_going = 1; bgav_track_t * track; char * tmp_string; /* Create track */ ctx->tt = bgav_track_table_create(1); track = ctx->tt->cur; /* Check file magic */ if(!read_chunk_header(ctx->input, &ch) || (ch.fourcc != BGAV_MK_FOURCC('F','O','R','M'))) return 0; if(!bgav_input_read_fourcc(ctx->input, &fourcc)) return 0; /* Allocate private struct */ priv = calloc(1, sizeof(*priv)); ctx->priv = priv; if(fourcc == BGAV_MK_FOURCC('A','I','F','C')) { priv->is_aifc = 1; } else if(fourcc != BGAV_MK_FOURCC('A','I','F','F')) { return 0; } /* Read chunks until we are done */ while(keep_going) { if(!read_chunk_header(ctx->input, &ch)) return 0; switch(ch.fourcc) { case BGAV_MK_FOURCC('C','O','M','M'): s = bgav_track_add_audio_stream(track, ctx->opt); memset(&comm, 0, sizeof(comm)); if(!comm_chunk_read(&ch, ctx->input, &comm, priv->is_aifc)) { return 0; } s->data.audio.format.samplerate = comm.samplerate; s->data.audio.format.num_channels = comm.num_channels; s->data.audio.bits_per_sample = comm.num_bits; /* * Multichannel support according to * http://music.calarts.edu/~tre/AIFFC/ */ switch(s->data.audio.format.num_channels) { case 1: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_CENTER; break; case 2: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_RIGHT; break; case 3: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_CENTER; s->data.audio.format.channel_locations[2] = GAVL_CHID_FRONT_RIGHT; break; case 4: /* Note: 4 channels can also be "left center right surround" but we believe, that quad is more common */ s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_RIGHT; s->data.audio.format.channel_locations[2] = GAVL_CHID_REAR_LEFT; s->data.audio.format.channel_locations[3] = GAVL_CHID_REAR_RIGHT; break; case 6: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_CENTER_LEFT; s->data.audio.format.channel_locations[2] = GAVL_CHID_FRONT_CENTER; s->data.audio.format.channel_locations[3] = GAVL_CHID_FRONT_RIGHT; s->data.audio.format.channel_locations[4] = GAVL_CHID_FRONT_CENTER_RIGHT; s->data.audio.format.channel_locations[5] = GAVL_CHID_REAR_CENTER; break; } if(!priv->is_aifc) s->fourcc = BGAV_MK_FOURCC('a','i','f','f'); else if(comm.compression_type == BGAV_MK_FOURCC('N','O','N','E')) s->fourcc = BGAV_MK_FOURCC('a','i','f','f'); else s->fourcc = comm.compression_type; switch(s->fourcc) { case BGAV_MK_FOURCC('a','i','f','f'): if(s->data.audio.bits_per_sample <= 8) { s->data.audio.block_align = comm.num_channels; } else if(s->data.audio.bits_per_sample <= 16) { s->data.audio.block_align = 2 * comm.num_channels; } else if(s->data.audio.bits_per_sample <= 24) { s->data.audio.block_align = 3 * comm.num_channels; } else if(s->data.audio.bits_per_sample <= 32) { s->data.audio.block_align = 4 * comm.num_channels; } else { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "%d bit aiff not supported", s->data.audio.bits_per_sample); return 0; } s->data.audio.format.samples_per_frame = 1024; priv->samples_per_block = 1; break; case BGAV_MK_FOURCC('f','l','3','2'): s->data.audio.block_align = 4 * comm.num_channels; priv->samples_per_block = 1; break; case BGAV_MK_FOURCC('f','l','6','4'): s->data.audio.block_align = 8 * comm.num_channels; priv->samples_per_block = 1; s->data.audio.format.samples_per_frame = 1024; break; case BGAV_MK_FOURCC('a','l','a','w'): case BGAV_MK_FOURCC('A','L','A','W'): case BGAV_MK_FOURCC('u','l','a','w'): case BGAV_MK_FOURCC('U','L','A','W'): s->data.audio.block_align = comm.num_channels; priv->samples_per_block = 1; s->data.audio.format.samples_per_frame = 1024; break; #if 0 case BGAV_MK_FOURCC('G','S','M',' '): s->data.audio.block_align = 33; priv->samples_per_block = 160; s->data.audio.format.samples_per_frame = 160; break; #endif case BGAV_MK_FOURCC('M','A','C','3'): s->data.audio.block_align = comm.num_channels * 2; priv->samples_per_block = 6; s->data.audio.format.samples_per_frame = 6*128; break; case BGAV_MK_FOURCC('M','A','C','6'): s->data.audio.block_align = comm.num_channels; priv->samples_per_block = 6; s->data.audio.format.samples_per_frame = 6*128; break; default: bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Compression %c%c%c%c not supported", comm.compression_type >> 24, (comm.compression_type >> 16) & 0xff, (comm.compression_type >> 8) & 0xff, (comm.compression_type) & 0xff); return 0; } break; case BGAV_MK_FOURCC('N','A','M','E'): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_TITLE, tmp_string); break; case BGAV_MK_FOURCC('A','U','T','H'): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_AUTHOR, tmp_string); break; case BGAV_MK_FOURCC('(','c',')',' '): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_COPYRIGHT, tmp_string); break; case BGAV_MK_FOURCC('A','N','N','O'): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_COMMENT, tmp_string); break; case BGAV_MK_FOURCC('S','S','N','D'): bgav_input_skip(ctx->input, 4); /* Offset */ bgav_input_skip(ctx->input, 4); /* Blocksize */ ctx->data_start = ctx->input->position; ctx->flags |= BGAV_DEMUXER_HAS_DATA_START; priv->data_size = ch.size - 8; ctx->tt->cur->audio_streams->duration = pos_2_time(ctx, priv->data_size + ctx->data_start); track->duration = gavl_time_unscale(s->data.audio.format.samplerate, ctx->tt->cur->audio_streams->duration); keep_going = 0; break; default: bgav_input_skip(ctx->input, PADD(ch.size)); break; } } if(ctx->input->input->seek_byte) ctx->flags |= BGAV_DEMUXER_CAN_SEEK; if(priv->is_aifc) gavl_metadata_set(&ctx->tt->cur->metadata, GAVL_META_FORMAT, "AIFF-C"); else gavl_metadata_set(&ctx->tt->cur->metadata, GAVL_META_FORMAT, "AIFF"); ctx->index_mode = INDEX_MODE_PCM; return 1; }
bool rpng_iterate_image(rpng_t *rpng) { unsigned i; struct png_chunk chunk = {0}; uint8_t *buf = (uint8_t*)rpng->buff_data; if (!read_chunk_header(buf, &chunk)) return false; *buf += 8; #if 0 for (i = 0; i < 4; i++) { fprintf(stderr, "chunktype: %c\n", chunk.type[i]); } #endif switch (png_chunk_type(&chunk)) { case PNG_CHUNK_NOOP: default: break; case PNG_CHUNK_ERROR: goto error; case PNG_CHUNK_IHDR: if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend) goto error; if (chunk.size != 13) goto error; if (!png_parse_ihdr(buf, &rpng->ihdr)) goto error; if (!png_process_ihdr(&rpng->ihdr)) goto error; rpng->has_ihdr = true; break; case PNG_CHUNK_PLTE: { unsigned entries = chunk.size / 3; if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat || rpng->has_trns) goto error; if (chunk.size % 3) goto error; if (entries > 256) goto error; buf += 8; if (!png_read_plte(buf, rpng->palette, entries)) goto error; rpng->has_plte = true; } break; case PNG_CHUNK_tRNS: { unsigned entries = chunk.size / 3; if (rpng->has_idat) goto error; if (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT) { /* we should compare with the number of palette entries */ if (chunk.size > 256) goto error; if (!png_read_trns(buf, rpng->palette, chunk.size)) goto error; } /* TODO: support colorkey in grayscale and truecolor images */ rpng->has_trns = true; } break; case PNG_CHUNK_IDAT: if (!(rpng->has_ihdr) || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !(rpng->has_plte))) goto error; if (!png_realloc_idat(&chunk, &rpng->idat_buf)) goto error; buf += 8; for (i = 0; i < chunk.size; i++) rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i]; rpng->idat_buf.size += chunk.size; rpng->has_idat = true; break; case PNG_CHUNK_IEND: if (!(rpng->has_ihdr) || !(rpng->has_idat)) goto error; rpng->has_iend = true; goto error; } rpng->buff_data += chunk.size + 12; return true; error: return false; }