int write_data_sch(struct object_descriptor *descr, int offset, int size, const void *buffer) { struct write_packet p; int res, wsize; res = io_write(descr, offset, size, buffer); if (res >= 0) { if (offset != -1) descr->meta.size = descr->meta.size > (unsigned int)(offset + size) ? descr->meta.size : offset + size; else descr->meta.size += size; write_metadata(descr); } if (res < 0) { p.obj = descr->id; p.offset = offset; p.size = size; for (unsigned int i = 0; i < peers.size(); i++) { pthread_mutex_lock(&peer_locks[i]); forward_data(peer_srv_socks[i], OP_WRITE, OS_MASTER, &p, sizeof(p), buffer, size); res = receive_reply(peer_srv_socks[i], &wsize, sizeof(wsize)); pthread_mutex_unlock(&peer_locks[i]); if (res >= 0) return wsize; } } return res; }
FLAC__bool do_major_operation__list(const char *filename, FLAC__Metadata_Chain *chain, const CommandLineOptions *options) { FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new(); FLAC__StreamMetadata *block; FLAC__bool ok = true; unsigned block_number; if(0 == iterator) die("out of memory allocating iterator"); FLAC__metadata_iterator_init(iterator, chain); block_number = 0; do { block = FLAC__metadata_iterator_get_block(iterator); ok &= (0 != block); if(!ok) fprintf(stderr, "%s: ERROR: couldn't get block from chain\n", filename); else if(passes_filter(options, FLAC__metadata_iterator_get_block(iterator), block_number)) write_metadata(filename, block, block_number, !options->utf8_convert, options->application_data_format_is_hexdump); block_number++; } while(ok && FLAC__metadata_iterator_next(iterator)); FLAC__metadata_iterator_delete(iterator); return ok; }
static void materialize_imgspec(struct imgspec* const spec) { if (ftruncate(spec->sp_fd, spec->sp_upperbound) < 0) error("failed to truncate the image file: %s", strerror(errno)); char* image = mmap(NULL, spec->sp_upperbound, PROT_READ | PROT_WRITE, MAP_SHARED, spec->sp_fd, 0); if (image == MAP_FAILED) error("failed to mmap the image file: %s", strerror(errno)); __u64 offset = superblock_offset(spec) + sizeof(struct microfs_sb); offset = write_decompressordata(spec, image, offset); offset = write_metadata(spec, image, offset); offset = write_data(spec, image, offset); const __u64 innersz = offset; const __u64 outersz = sz_blkceil(offset, spec->sp_szpad); write_superblock(spec, image, innersz); if (munmap(image, spec->sp_upperbound) < 0) error("failed to unmap the image: %s", strerror(errno)); if (ftruncate(spec->sp_fd, outersz) < 0) error("failed to set the final image size: %s", strerror(errno)); message(VERBOSITY_1, "Inner image size: %llu bytes", innersz); message(VERBOSITY_0, "Outer image size: %llu bytes", outersz); }
static void cddb_thread (void *params_void) { struct cddb_thread_params *params = (struct cddb_thread_params *)params_void; char disc_list[(CDDB_CATEGORY_SIZE + CDDB_DISCID_SIZE + 1) * MAX_CDDB_DISCS]; const int num_discs = resolve_disc(params->disc, disc_list); if (num_discs <= 0) { trace("disc not resolved\n"); cleanup_thread_params(params); return; } trace("disc resolved\n"); char num_tracks[4]; int track_count = cddb_disc_get_track_count(params->disc); snprintf(num_tracks, sizeof(num_tracks), "%02d", track_count); for (size_t i = 0; params->items[i]; i++) { deadbeef->pl_add_meta(params->items[i], CDDB_IDS_TAG, disc_list); write_metadata(params->items[i], params->disc, num_tracks); } cleanup_thread_params(params); ddb_playlist_t *plt = deadbeef->plt_get_curr (); if (plt) { deadbeef->plt_modified (plt); deadbeef->plt_unref (plt); } deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0); }
void init_server() { struct object_descriptor d, *obj; struct stat f_stat; char *path = (char*)malloc(strlen(filesystem_path) + 256); obj = read_metadata(path_to_id("/"), NULL); if (obj) { free(path); return; } /* meta / */ strcpy(path, filesystem_path); strcat(path, "/"); stat(path, &f_stat); memset(&d, 0, sizeof(d)); d.id = path_to_id("/"); if (f_stat.st_mode & S_IFDIR) d.meta.type = ODT_DIR; else d.meta.type = ODT_FILE; d.meta.size = 0; strcpy((char*)d.meta.name, "/"); write_metadata(&d); /* data / */ const char data[] = ""; create_data(&d, 0, data); free(path); }
void write_chunk(M1_compiler *comp, m1_chunk *c) { fprintf(OUT, ".chunk \"%s\"\n", c->name); write_consts(comp, &c->constants); write_metadata(comp, c); fprintf(OUT, ".bytecode\n"); }
static void write_style_defs(FILE *f,const kate_style *ks,size_t indent) { char *sindent=(char*)kate_malloc(1+indent); size_t n; for (n=0;n<indent;++n) sindent[n]=' '; sindent[indent]=0; { const char *halign=halign2text(ks->halign); const char *valign=valign2text(ks->valign); kate_color tc=ks->text_color,bc=ks->background_color,dc=ks->draw_color; fprintf( f, "%s%s %s\n", sindent,halign,valign ); write_color(f,"text color",&tc,indent); write_color(f,"background color",&bc,indent); write_color(f,"draw color",&dc,indent); if (ks->font) { fprintf(f,"%sfont \"%s\"\n",sindent,ks->font); } if (ks->font_width>=0 || ks->font_height>=0) { if (ks->font_width==ks->font_height) { fprintf(f,"%sfont size %f%s\n",sindent,ks->font_height,metric2suffix(ks->font_metric)); } else { if (ks->font_width>=0) fprintf(f,"%sfont width %f%s\n",sindent,ks->font_width,metric2suffix(ks->font_metric)); if (ks->font_height>=0) fprintf(f,"%sfont height %f%s\n",sindent,ks->font_height,metric2suffix(ks->font_metric)); } } if (ks->left_margin!=0 || ks->top_margin!=0 || ks->right_margin!=0 || ks->bottom_margin!=0) { const char *margin_metric=metric2suffix(ks->margin_metric); fprintf( f,"%smargins %f%s %f%s %f%s %f%s\n", sindent, ks->left_margin,margin_metric,ks->top_margin,margin_metric, ks->right_margin,margin_metric,ks->bottom_margin,margin_metric ); } if (ks->bold) fprintf(f,"%sbold\n",sindent); if (ks->italics) fprintf(f,"%sitalics\n",sindent); if (ks->underline) fprintf(f,"%sunderline\n",sindent); if (ks->strike) fprintf(f,"%sstrike\n",sindent); if (ks->justify) fprintf(f,"%sjustify\n",sindent); fprintf(f,"%swrap %s\n",sindent,wrap2text(ks->wrap_mode)); if (ks->meta) write_metadata(f,ks->meta,indent); } kate_free(sindent); }
static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event) { int res = 0; char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = ""; int fd; FILE *logfile; event_node_t *elp = event; if (!ast_strlen_zero(event_spool_dir)) { /* Make a template */ ast_copy_string(workstring, event_spool_dir, sizeof(workstring)); strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1); /* Make the temporary file */ fd = mkstemp(workstring); if(fd == -1){ ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't make temporary file\n"); ast_log(LOG_DEBUG,"AlarmReceiver: can't make temporary file\n"); res = -1; } if(!res){ logfile = fdopen(fd, "w"); if(logfile){ /* Write the file */ res = write_metadata(logfile, signalling_type, chan); if(!res) while((!res) && (elp != NULL)){ res = write_event(logfile, elp); elp = elp->next; } if(!res){ if(fflush(logfile) == EOF) res = -1; if(!res){ if(fclose(logfile) == EOF) res = -1; } } } else res = -1; } } return res; }
static void _mouse_over_image_callback(gpointer instace, gpointer user_data) { const dt_lib_module_t *self = (dt_lib_module_t *)user_data; const dt_lib_metadata_t *d = (dt_lib_metadata_t *)self->data; /* lets trigger an expose for a redraw of widget */ if(d->editing) { write_metadata(user_data); gtk_window_set_focus(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), NULL); } gtk_widget_queue_draw(GTK_WIDGET(self->widget)); }
static void write_region_defs(FILE *f,const kate_region *kr,size_t indent) { char *sindent=(char*)kate_malloc(1+indent); size_t n; for (n=0;n<indent;++n) sindent[n]=' '; sindent[indent]=0; fprintf(f,"%s%s position %d %d size %d %d\n",sindent,metric2text(kr->metric),kr->x,kr->y,kr->w,kr->h); if (kr->style>=0) fprintf(f,"%sdefault style %d\n",sindent,kr->style); if (kr->clip) fprintf(f,"%sclip\n",sindent); if (kr->meta) write_metadata(f,kr->meta,indent); kate_free(sindent); }
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { const dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_metadata_t *d = (dt_lib_metadata_t *)self->data; switch(event->keyval) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: write_metadata(user_data); gtk_window_set_focus(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), NULL); break; case GDK_KEY_Escape: update(user_data, FALSE); gtk_window_set_focus(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), NULL); break; case GDK_KEY_Tab: write_metadata(user_data); break; default: d->editing = TRUE; } return FALSE; }
static void write_directory_data(State *s, DirData *dir) { /* If no extent allocated, no data * can be written. */ if (!dir->record->extent_len) return; /* Only write metadata when there is data */ if (dir->buf) { mkfs_swap_dir_from_cpu(s, dir); write_metadata(s, dir->record, dir->buf); mkfs_swap_dir_to_cpu(s, dir); } }
void reqs_write(int node, struct write_packet *p, const void *buffer) { struct object_descriptor obj; if (!read_metadata(p->obj, &obj)) return; write_data(&obj, p->offset, p->size, buffer); if (p->offset != -1) obj.meta.size = obj.meta.size > p->offset + p->size ? obj.meta.size : p->offset + p->size; else obj.meta.size += p->size; write_metadata(&obj); send_reply(peer_cli_socks[node], NULL, 0); }
static int log_super(struct log_writes_c *lc) { struct log_write_super super; super.magic = cpu_to_le64(WRITE_LOG_MAGIC); super.version = cpu_to_le64(WRITE_LOG_VERSION); super.nr_entries = cpu_to_le64(lc->logged_entries); super.sectorsize = cpu_to_le32(lc->sectorsize); if (write_metadata(lc, &super, sizeof(super), NULL, 0, 0)) { DMERR("Couldn't write super"); return -1; } return 0; }
int create_object_slv(oid_t obj, const char *name, int type) { struct object_descriptor o; if (read_metadata(obj, &o)) return EEXIST; memset(&o, 0, sizeof(o)); o.id = obj; o.meta.type = type; strcpy((char*)o.meta.name, name); write_metadata(&o); create_data(&o, 0, NULL); return 0; }
static void write_palette_defs(FILE *f,const kate_palette *kp,size_t indent) { size_t s; char *sindent=(char*)kate_malloc(1+indent); size_t n; for (n=0;n<indent;++n) sindent[n]=' '; sindent[indent]=0; fprintf(f,"%s%lu colors {\n",sindent,(unsigned long)kp->ncolors); for (s=0;s<kp->ncolors;++s) { const kate_color *kc=kp->colors+s; fprintf(f,"%s { %d %d %d %d },\n",sindent,kc->r,kc->g,kc->b,kc->a); } fprintf(f,"%s}\n",sindent); if (kp->meta) write_metadata(f,kp->meta,indent); kate_free(sindent); }
static void write_motion_defs(FILE *f,const kate_info *ki,const kate_motion *km,size_t indent) { size_t s; char *sindent=(char*)kate_malloc(1+indent); size_t n; for (n=0;n<indent;++n) sindent[n]=' '; sindent[indent]=0; fprintf(f,"%ssemantics %s\n",sindent,semantics2text(km->semantics)); if (km->periodic) fprintf(f,"%speriodic\n",sindent); if (km->x_mapping!=kate_motion_mapping_none || km->y_mapping!=kate_motion_mapping_none) { if (km->x_mapping==km->y_mapping) { fprintf(f,"%smapping %s\n",sindent,mapping2text(km->x_mapping)); } else { /* two calls as mapping2text can return a static buffer */ fprintf(f,"%smapping %s",sindent,mapping2text(km->x_mapping)); fprintf(f," %s\n",mapping2text(km->y_mapping)); } } for (s=0;s<km->ncurves;++s) { const kate_curve *kc=km->curves[s]; int idx; idx=kate_find_curve(ki,kc); if (idx<0) { fprintf(f,"%scurve {\n",sindent); write_curve_defs(f,kc,indent+2); fprintf(f,"%s}",sindent); } else { fprintf(f,"%scurve %d",sindent,idx); } if (km->durations[s]!=-1) { fprintf(f," for %.16g\n",km->durations[s]); } else { fprintf(f,"\n"); } } if (km->meta) write_metadata(f,km->meta,indent); kate_free(sindent); }
/*! * \brief Log events if configuration key logindividualevents is enabled or on exit * * \param chan Asterisk Channel * \param signalling_type Signaling Type * \param event Event Structure * \param no_checksum Expecting messages without checksum * * \retval 0 success * \retval -1 failure */ static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event, int no_checksum) { char workstring[sizeof(event_spool_dir) + sizeof(event_file)] = ""; int fd; FILE *logfile; event_node_t *elp = event; if (!ast_strlen_zero(event_spool_dir)) { /* Make a template */ ast_copy_string(workstring, event_spool_dir, sizeof(workstring)); strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1); /* Make the temporary file */ fd = mkstemp(workstring); if (fd == -1) { ast_verb(3, "AlarmReceiver: can't make temporary file\n"); ast_debug(1, "AlarmReceiver: can't make temporary file\n"); return -1; } if ((logfile = fdopen(fd, "w")) == NULL) { return -1; } /* Write the file */ if (write_metadata(logfile, signalling_type, chan, no_checksum)) { fflush(logfile); fclose(logfile); return -1; } while ((elp != NULL) && (write_event(logfile, elp) == 0)) { elp = elp->next; } fflush(logfile); fclose(logfile); } return 0; }
static gboolean gst_wavenc_event (GstPad * pad, GstEvent * event) { gboolean res = TRUE; GstWavEnc *wavenc; wavenc = GST_WAVENC (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS:{ GST_DEBUG_OBJECT (wavenc, "got EOS"); #if 0 /* Write our metadata if we have any */ if (wavenc->metadata) { write_metadata (wavenc); write_cues (wavenc); write_labels (wavenc); } #endif /* write header with correct length values */ gst_wavenc_push_header (wavenc, wavenc->length); /* we're done with this file */ wavenc->finished_properly = TRUE; /* and forward the EOS event */ res = gst_pad_event_default (pad, event); break; } case GST_EVENT_NEWSEGMENT: /* Just drop it, it's probably in TIME format * anyway. We'll send our own newsegment event */ gst_event_unref (event); break; default: res = gst_pad_event_default (pad, event); break; } gst_object_unref (wavenc); return res; }
static void write_bitmap_defs(FILE *f,const kate_bitmap *kb,size_t indent) { size_t w,h,p; char *sindent=(char*)kate_malloc(1+indent); size_t n; for (n=0;n<indent;++n) sindent[n]=' '; sindent[indent]=0; switch (kb->type) { case kate_bitmap_type_png: fprintf(f,"%s%lux%lu png %lu {\n",sindent,(unsigned long)kb->width,(unsigned long)kb->height,(unsigned long)kb->size); for (p=0;p<kb->size;++p) { if (p%16==0) fprintf(f,"%s",sindent); fprintf(f," 0x%02x",kb->pixels[p]); if (p%16==15 || p==kb->size-1) fprintf(f,"\n"); } fprintf(f,"%s}\n",sindent); break; case kate_bitmap_type_paletted: fprintf(f,"%s%lux%lux%d {\n",sindent,(unsigned long)kb->width,(unsigned long)kb->height,kb->bpp); p=0; for (h=0;h<kb->height;++h) { fprintf(f,"%s ",sindent); for (w=0;w<kb->width;++w) { fprintf(f," %3d",kb->pixels[p++]); } fprintf(f,"\n"); } fprintf(f,"%s}\n",sindent); break; default: fprintf(stderr,"Error: unknown bitmap type: %d\n",kb->type); break; } if (kb->x_offset || kb->y_offset) { fprintf(f,"%soffset %d %d\n",sindent,kb->x_offset,kb->y_offset); } if (kb->palette>=0) fprintf(f,"%sdefault palette %d\n",sindent,kb->palette); if (kb->meta) write_metadata(f,kb->meta,indent); kate_free(sindent); }
static void write_subrecord(struct record *r, WRBUF w, struct conf_service *service, int show_details) { const char *name = session_setting_oneval( client_get_database(r->client), PZ_NAME); wrbuf_puts(w, " <location id=\""); wrbuf_xmlputs(w, client_get_id(r->client)); wrbuf_puts(w, "\"\n"); wrbuf_puts(w, " name=\""); wrbuf_xmlputs(w, *name ? name : "Unknown"); wrbuf_puts(w, "\" "); wrbuf_puts(w, "checksum=\""); wrbuf_printf(w, "%u", r->checksum); wrbuf_puts(w, "\">\n"); write_metadata(w, service, r->metadata, show_details, 2); wrbuf_puts(w, " </location>\n"); }
void reqm_write(int sock, struct write_packet *p, const void *buffer, int unlock) { struct object_descriptor obj; int wsize, node; if (!read_metadata(p->obj, &obj)) { if (unlock) unlock_object(p->obj); send_error(sock, ENOENT); return; } wsize = write_data(&obj, p->offset, p->size, buffer); if (p->offset != -1) obj.meta.size = obj.meta.size > p->offset + p->size ? obj.meta.size : p->offset + p->size; else obj.meta.size += p->size; write_metadata(&obj); pthread_mutex_lock(&replicas_lock); for (unsigned int i = 0; i < replicas.size(); i++) { if (!memcmp(&replicas[i].id, &p->obj, sizeof(oid_t))) { node = replicas[i].node; pthread_mutex_lock(&peer_locks[node]); forward_data(peer_srv_socks[node], OP_WRITE, OS_SLAVE, p, sizeof(*p), buffer, p->size); receive_reply(peer_srv_socks[node], NULL, 0); pthread_mutex_unlock(&peer_locks[node]); } } pthread_mutex_unlock(&replicas_lock); if (unlock) unlock_object(p->obj); send_reply(sock, &wsize, sizeof(wsize)); }
/** * Sign the file at the specified path using the private * key with the specified label on a token with the specified pin * and optionally with the beginning hash state saved in the * specified metadata_t from the previous signing. */ static void sign(const char* path, const char* pin, const char* label, metadata_t* md) { int n, err, sig_size; sha256_context ctx; sha256_context ctx_cpy; const unsigned char *pCms = 0; unsigned char buf[0x10000], hash[32]; /* 32 => 256-bit sha256 */ char sig_path[MAX_PATH] = ""; FILE * fpi = 0, * fpo = 0; /* Open the data file for reading */ fpi = fopen(path, "rb"); if (!fpi) { int e = errno; log_err("error opening file '%s' for reading: %s", path, strerror(e)); goto sign_error; } /* Get the saved hash context or start a new one */ if (!md) { /* No metadata */ /* Start a new hash context */ sha256_starts(&ctx); } else { /* Metadata exists */ /* Restore the saved hash context */ int ok; /* Get the saved hashed content length (hcl) */ offset_t hcl = sizeof(hcl) == 4 ? md->cll : (offset_t)md->clh << 32 | md->cll; /* Adjust the hcl back to the last block boundary */ hcl = hcl - hcl % sizeof(ctx.buffer); /* Restore the "total" (hcl) field to the hash context */ ctx.total[0] = (unsigned int)hcl; ctx.total[1] = (unsigned int)(hcl >> 32); /* Restore the state field to the hash context */ memcpy(&ctx.state, &md->state, sizeof(ctx.state)); /* Seek to the position of hcl minus one & verify last byte still exists */ ok = hcl <= 0 || fseeko(fpi, hcl - 1, SEEK_SET) == 0 && getc(fpi) >= 0; if (!ok) { if (sizeof(hcl) == 4) /* 32-bit hcl */ log_err("error seeking in '%s' to pos %d", path, (int)hcl); else /* 64-bit hcl */ log_err("error seeking in '%s' to pos %lld", path, hcl); goto sign_error; } } /* Create/Continue a SHA-256 hash of the file */ for (;;) { int n = fread(buf, 1, sizeof(buf), fpi); if (n <= 0) break; sha256_update(&ctx, buf, n); } /* Check for error during read */ if (ferror(fpi)) { log_err("error reading file '%s'", path); goto sign_error; } /* Close the data file */ err = fclose(fpi); if (err) { int e = errno; log_err("error closing file '%s': %s", path, strerror(e)); goto sign_error; } fpi = 0; /* Clone the unfinalized hash context to save in the metadata */ memcpy(&ctx_cpy, &ctx, sizeof(ctx)); /* Finalize the hash for the current sig */ sha256_finish(&ctx, hash); /* Sign the hash with the token; creates CMS document & puts ptr in pCMS WARNING: sign_hash is not re-entrant (see sc-hsm-ultralite.c) */ sig_size = sign_hash(pin, label, hash, sizeof(hash), &pCms); if (sig_size <= 0) { goto sign_error; } /* Open the new sig file for writing */ n = snprintf(sig_path, sizeof(sig_path), "%s%s", path, sig_ext); if (n < 0 || n >= sizeof(sig_path)) { log_err("error building sig file path '%s%s'", path, sig_ext); goto sign_error; } fpo = fopen(sig_path, "wb"); if (!fpo) { int e = errno; log_err("error opening sig file '%s' for writing: %s", sig_path, strerror(e)); goto sign_error; } /* Write the CMS document to the sig file */ n = fwrite(pCms, 1, sig_size, fpo); if (n != sig_size) { log_err("error writing to sig file '%s'", sig_path); goto sign_error; } /* Save "total" (hcl) & unfinalized hash state at end of sig file */ err = write_metadata(fpo, &ctx_cpy); if (err) { log_err("error writing metadata to sig file '%s'", sig_path); goto sign_error; } /* Close the sig file */ err = fclose(fpo); if (err) { log_err("error closing sig file '%s'", sig_path); goto sign_error; } fpo = 0; /* Success */ log_inf("'%s' created", sig_path); return; sign_error: /* Close input file stream, if open */ if (fpi) { err = fclose(fpi); if (err) { int e = errno; log_err("error closing file '%s': %s", path, strerror(e)); } } /* Close output file stream, if open */ if (fpo) { err = fclose(fpo); if (err) { int e = errno; log_err("error closing sig file '%s': %s", sig_path, strerror(e)); } } return; }
void sort(char *inputfile, char *outputfile, int numattrs, int attributes[], int bufsize) { // open stream to read data file printf("Buffer size: %d bytes\n", bufsize); printf("Block size: %d bytes\n", DISK_BLOCK_SIZE); printf("Reading from: %s\n", inputfile); FILE *in = fopen(inputfile, "r"); // read metadata metadata m; m.record_size = m.header_size = 0; fread(&m.numattrs, sizeof(unsigned int), 1, in); m.header_size += sizeof(unsigned int) + 2 * m.numattrs * sizeof(int); m.attrlist = (attribute *) malloc(sizeof(attribute) * m.numattrs); printf("Header size: %d bytes\n", m.header_size); int i, j; for (i = 0; i < m.numattrs; i++) { fread(&m.attrlist[i].type, sizeof(int), 1, in); fread(&m.attrlist[i].size, sizeof(int), 1, in); m.record_size += m.attrlist[i].size; } printf("Record size: %d bytes\n", m.record_size); _meta = m; _meta.num_comp_attrs = numattrs; _meta.comparable_attrs = attributes; // max no. of disk blocks that fit in the buffer int num_records_in_buffer = bufsize / m.record_size; int num_records_in_block = DISK_BLOCK_SIZE / m.record_size; int num_blocks_in_buffer = bufsize / DISK_BLOCK_SIZE; printf("Records in block: %d\n", num_records_in_block); printf("Blocks in buffer: %d \n", num_blocks_in_buffer); // the buffer char *buffer = (char *) malloc(bufsize); // create the initial set of runs size_t records_read, records_written; i = 0; char run_name[20]; FILE *out; unsigned int num_recs_read = 0; unsigned int num_recs_written = 0; while (1) { records_read = fread(buffer, m.record_size, num_records_in_buffer, in); if (records_read == 0) break; num_recs_read += records_read; // sort the chunk qsort(buffer, records_read, m.record_size, compare_records); // write sorted chunk to a run file i++; sprintf(run_name, "run_%d.bin", i); out = fopen(run_name, "w"); write_metadata(out, m); records_written = fwrite(buffer, m.record_size, records_read, out); num_recs_written += records_written; fclose(out); } printf("Read %d records from input file.\n", num_recs_read); // number of generated runs int init_num_runs = i; printf("Number of initial runs generated: %d\nMerging...\n", i); /********************************* MERGE ********************************/ // number of runs in a pass int num_runs = init_num_runs; // max no. of runs we can merge at once int max_merge_runs = (bufsize / DISK_BLOCK_SIZE) - 1; int start = 1; int interm_runp = 1; char temp_run_name[20]; int runs_left_this_pass = num_runs; // run multiple passes over the runs to merge into one file while (1) { // check if we have to move to the next pass if (runs_left_this_pass == 0) { start = 1; interm_runp = 1; int merged_at_once = (num_runs < max_merge_runs ? num_runs : max_merge_runs); if (num_runs == merged_at_once) { // the final merged output of all runs is in run_1.bin // rename it to 'outputfile' rename("run_1.bin", outputfile); printf("Done.\nOutput written to: %s\n", outputfile); break; } num_runs = (num_runs / merged_at_once) + 1 * (num_runs % merged_at_once != 0); runs_left_this_pass = num_runs; } // decide how many runs to merge at once int merge_at_once = (runs_left_this_pass < max_merge_runs ? runs_left_this_pass : max_merge_runs); sprintf(temp_run_name, "run_temp.bin"); // how much to read from one run file int blocks_per_run = (bufsize / (merge_at_once + 1)) / DISK_BLOCK_SIZE; int records_per_run = blocks_per_run * num_records_in_block; int bytes_per_run = blocks_per_run * num_records_in_block * m.record_size; // read from runs into buffer FILE **runs = (FILE **) malloc(merge_at_once * sizeof(FILE *)); char **run_pointers = (char **) malloc((merge_at_once + 1) * sizeof(char *)); char **run_bp = (char **) malloc((merge_at_once + 1) * sizeof(char *)); char **run_ep = (char **) malloc((merge_at_once + 1) * sizeof(char *)); heap *HEAP = (heap *) malloc(sizeof(heap)); heap_init(HEAP, compare_records); for (i = 0; i < merge_at_once; i++) { sprintf(run_name, "run_%d.bin", i + start); runs[i] = fopen(run_name, "r"); fseek(runs[i], m.header_size, SEEK_SET); char *buffer_start_addr = buffer + i * bytes_per_run; fread(buffer_start_addr, num_records_in_block * m.record_size, blocks_per_run, runs[i]); run_bp[i] = buffer_start_addr; heap_push(HEAP, run_bp[i]); run_pointers[i] = run_bp[i] + m.record_size; run_ep[i] = run_bp[i] + bytes_per_run; } // the output buffer run_bp[i] = run_pointers[i] = buffer + i * bytes_per_run; // open a temporary run file for storing merged contents of all the generated runs FILE *temp_out = fopen(temp_run_name, "w"); write_metadata(temp_out, m); fclose(temp_out); // read chunks of data from each run file into a heap // and write to a temp run file until all the run files become empty num_recs_read = 0; int push = 0; int read_from_runs = 0; while (1) { // get min record from heap, and compute the index of the parent run void *min_rec = heap_pop(HEAP); if (!min_rec) { // write out whatever is left in the output buffer and exit if (run_pointers[merge_at_once] > run_bp[merge_at_once]) { FILE *output_run = fopen(temp_run_name, "a"); size_t check = fwrite(run_bp[merge_at_once], 1, run_pointers[merge_at_once] - run_bp[merge_at_once], output_run); fclose(output_run); // printf("Emptying output buffer, writing %d bytes\n", check); } break; } int min_rec_run = get_run_number(min_rec, run_bp, merge_at_once); // copy the min record popped from the heap into the output run memcpy(run_pointers[merge_at_once], min_rec, m.record_size); run_pointers[merge_at_once] += m.record_size; // fetch a new record from the run and push into heap, // adjusting the run pointer if (run_pointers[min_rec_run - 1] < run_ep[min_rec_run - 1]) { heap_push(HEAP, run_pointers[min_rec_run - 1]); push++; run_pointers[min_rec_run - 1] += m.record_size; } else if (run_pointers[min_rec_run - 1] >= run_ep[min_rec_run - 1]) { size_t check = fread(run_bp[min_rec_run - 1], m.record_size, records_per_run, runs[min_rec_run - 1]); read_from_runs += check; // reset the run pointer if (check > 0) { run_pointers[min_rec_run - 1] = run_bp[min_rec_run - 1]; run_ep[min_rec_run - 1] = run_bp[min_rec_run - 1] + check * m.record_size; // push first record from fresh lot into heap heap_push(HEAP, run_pointers[min_rec_run - 1]); push++; run_pointers[min_rec_run - 1] += m.record_size; } } // check for overflow of the output run, // write to output run if an overflow is detected if (run_pointers[merge_at_once] >= run_bp[merge_at_once] + bytes_per_run) { FILE *output_run = fopen(temp_run_name, "a"); size_t check = fwrite(run_bp[merge_at_once], m.record_size, records_per_run, output_run); fclose(output_run); num_recs_read += check; // reset the run pointer run_pointers[merge_at_once] = run_bp[merge_at_once]; } } // clean up heap_destroy(HEAP); free(HEAP); free(run_ep); free(run_bp); free(run_pointers); for (i = 0; i < merge_at_once; i++) fclose(runs[i]); free(runs); // delete run files used to build this run file for (i = 0; i < merge_at_once; i++) { sprintf(run_name, "run_%d.bin", i + start); remove(run_name); } // compute number of runs left in this pass runs_left_this_pass -= merge_at_once; start += merge_at_once; // rename temp file to run_<index>.bin sprintf(run_name, "run_%d.bin", interm_runp); interm_runp++; rename(temp_run_name, run_name); // printf("Merged %d - %d into %s\n", start - merge_at_once, start - 1, run_name); } /************************* END MERGE *************************************/ // clean up free(m.attrlist); free(buffer); // close the input data file fclose(in); }
/****************************************************************************** MODULE: convert_espa_to_raw_binary_bip PURPOSE: Converts the internal ESPA raw binary file to a raw binary band interleave by pixel format. RETURN VALUE: Type = int Value Description ----- ----------- ERROR Error converting to BIP SUCCESS Successfully converted to BIP NOTES: 1. The bands in the XML file will be written, in order, to the BIP file. These bands must be of the same datatype and same size, otherwise this function will exit with an error. 2. If the data types are not the same, the convert_qa flag will allow the user to specify that the QA bands (uint8) should be included in the output BIP product however the QA bands will be converted to the same data type as the first band in the XML file. ******************************************************************************/ int convert_espa_to_raw_binary_bip ( char *espa_xml_file, /* I: input ESPA XML metadata filename */ char *bip_file, /* I: output BIP filename */ bool convert_qa, /* I: should the QA bands (uint8) be converted to the data type of band 1 (if QA bands are of a different data type)? */ bool del_src /* I: should the source files be removed after conversion? */ ) { char FUNC_NAME[] = "convert_espa_to_raw_binary_bip"; /* function name */ char errmsg[STR_SIZE]; /* error message */ char hdr_file[STR_SIZE]; /* name of the header file for this band */ char xml_file[STR_SIZE]; /* new XML file for the BIP product */ char envi_file[STR_SIZE]; /* name of the output ENVI header file */ char *cptr = NULL; /* pointer to empty space in the band name */ int i; /* looping variable for each band */ int l; /* looping variable for each line */ int s; /* looping variable for each sample */ int nbytes; /* number of bytes per pixel in the data type */ int nbytes_line; /* number of bytes per line in the data type */ int count; /* number of chars copied in snprintf */ int curr_pix; /* index for current pixel for QA conversion */ int curr_ipix; /* index for current input pixel */ int curr_opix; /* index for current output pixel */ int number_elements; /* number of elements per line for all bands */ void *file_buf = NULL; /* pointer to correct input file buffer */ uint8 *tmp_buf_u8 = NULL; /* buffer for uint8 QA data to be read */ uint8 *file_buf_u8 = NULL; /* buffer for uint8 data to be read */ int16 *file_buf_i16 = NULL; /* buffer for int16 data to be read */ int16 *file_buf_u16 = NULL; /* buffer for uint16 data to be read */ void *ofile_buf = NULL; /* pointer to correct output file buffer */ uint8 *ofile_buf_u8 = NULL; /* buffer for output uint8 data to be written */ int16 *ofile_buf_i16 = NULL;/* buffer for output int16 data to be written */ int16 *ofile_buf_u16 = NULL;/* buffer for output uint16 data to be written */ FILE **fp_rb = NULL; /* array of file pointers for the input raw binary files */ FILE *fp_bip = NULL; /* file pointer for the BIP raw binary file */ Espa_internal_meta_t xml_metadata; /* XML metadata structure to be populated by reading the input XML metadata file */ Espa_band_meta_t *bmeta=NULL; /* pointer to the array of bands metadata */ Espa_global_meta_t *gmeta=NULL; /* pointer to the global metadata structure */ Envi_header_t envi_hdr; /* output ENVI header information */ /* Validate the input metadata file */ if (validate_xml_file (espa_xml_file) != SUCCESS) { /* Error messages already written */ return (ERROR); } /* Initialize the metadata structure */ init_metadata_struct (&xml_metadata); /* Parse the metadata file into our internal metadata structure; also allocates space as needed for various pointers in the global and band metadata */ if (parse_metadata (espa_xml_file, &xml_metadata) != SUCCESS) { /* Error messages already written */ return (ERROR); } bmeta = xml_metadata.band; gmeta = &xml_metadata.global; printf ("convert_espa_to_raw_binary_bip processing %d bands ...\n", xml_metadata.nbands); /* Allocate file pointers for each band */ fp_rb = calloc (xml_metadata.nbands, sizeof (FILE *)); if (fp_rb == NULL) { sprintf (errmsg, "Allocating file pointers for all %d bands.", xml_metadata.nbands); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Loop through the bands in the XML file and verify they are all of the same data type and the same size */ for (i = 1; i < xml_metadata.nbands; i++) { if (bmeta[i].data_type != bmeta[0].data_type) { /* Convert uint8 data types that are flagged as QA */ if (convert_qa && bmeta[i].data_type == ESPA_UINT8 && !strcmp (bmeta[i].category, "qa")) { /* all is good, data type will be converted */ printf ("Band %s will be converted to native data type.\n", bmeta[i].name); } else { sprintf (errmsg, "Data type for band %d (%s) in the XML file " "does not match that of the first band. All bands must " "have the same data type to be written to BIP raw binary. " "Otherwise convert_qa can be specified to convert the QA " "bands (UINT8).", i+1, bmeta[i].name); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } else if (bmeta[i].nlines != bmeta[0].nlines) { sprintf (errmsg, "Number of lines for band %d (%s) in the XML file " "does not match that of the first band. All bands must be of " "the same image size to be written to BIP raw binary.", i+1, bmeta[i].name); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } else if (bmeta[i].nsamps != bmeta[0].nsamps) { sprintf (errmsg, "Number of samples for band %d (%s) in the XML " "file does not match that of the first band. All bands must " "be of the same image size to be written to BIP raw binary.", i+1, bmeta[i].name); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Loop through the bands in the XML file and open each band file for reading */ for (i = 0; i < xml_metadata.nbands; i++) { /* Open the file for this band of data to allow for reading */ fp_rb[i] = open_raw_binary (bmeta[i].file_name, "rb"); if (fp_rb[i] == NULL) { sprintf (errmsg, "Opening the input raw binary file: %s", bmeta[i].file_name); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Open the output BIP file to allow for writing */ fp_bip = open_raw_binary (bip_file, "wb"); if (fp_bip == NULL) { sprintf (errmsg, "Opening the output raw binary BIP file: %s", bip_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Allocate memory for a single line of the image and all the bands, based on the input data type of the first band */ switch (bmeta[0].data_type) { case ESPA_UINT8: nbytes = sizeof (uint8); break; case ESPA_INT16: nbytes = sizeof (int16); break; case ESPA_UINT16: nbytes = sizeof (uint16); break; default: sprintf (errmsg, "Unsupported data type. Currently only uint8, " "int16, and uint16 are supported."); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Input data */ file_buf = calloc (bmeta[0].nsamps * xml_metadata.nbands, nbytes); if (file_buf == NULL) { sprintf (errmsg, "Allocating memory for a line of %d-byte data " "containing %d samples for all %d bands.", nbytes, bmeta[0].nsamps, xml_metadata.nbands); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Output data */ ofile_buf = calloc (bmeta[0].nsamps * xml_metadata.nbands, nbytes); if (ofile_buf == NULL) { sprintf (errmsg, "Allocating memory for a line of %d-byte data " "containing %d samples for all %d bands.", nbytes, bmeta[0].nsamps, xml_metadata.nbands); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Assign the datatype-specific pointer to the void pointer to be used in the data conversion later for QA pixels */ switch (bmeta[0].data_type) { case ESPA_UINT8: file_buf_u8 = file_buf; ofile_buf_u8 = ofile_buf; break; case ESPA_INT16: file_buf_i16 = file_buf; ofile_buf_i16 = ofile_buf; break; case ESPA_UINT16: file_buf_u16 = file_buf; ofile_buf_u16 = ofile_buf; break; default: sprintf (errmsg, "Unsupported data type. Currently only uint8, " "int16, and uint16 are supported."); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* The QA bands will be converted so allocate space for a temporary UINT8 input array */ if (convert_qa) { tmp_buf_u8 = calloc (bmeta[0].nsamps, sizeof (uint8)); if (tmp_buf_u8 == NULL) { sprintf (errmsg, "Allocating memory for a line of QA data " "containing %d samples.", bmeta[0].nsamps); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Loop through the lines in the input raw binary file. Read each line for each band, put into the output BIP buffer, and write to the output file. */ nbytes_line = nbytes * bmeta[0].nsamps; for (l = 0; l < bmeta[0].nlines; l++) { if (l % 100 == 0) printf ("Line %d\n", l); for (i = 0; i < xml_metadata.nbands; i++) { /* Check to make sure the current band data type is the same as the output data type, otherwise this is a QA band that will get converted to the output data type */ if ((bmeta[0].data_type != bmeta[i].data_type) && (bmeta[i].data_type == ESPA_UINT8) && convert_qa) { /* Read the current line from the raw binary file into the temporary UINT8 buffer */ if (read_raw_binary (fp_rb[i], 1, bmeta[0].nsamps, sizeof (uint8), tmp_buf_u8) != SUCCESS) { sprintf (errmsg, "Reading QA data from the raw binary " "file for line %d and band %d", l, i); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Convert the data and write it to the output buffer */ if (bmeta[0].data_type == ESPA_INT16) { curr_pix = i * bmeta[0].nsamps; for (s = 0; s < bmeta[0].nsamps; s++, curr_pix++) file_buf_i16[curr_pix] = (int16) tmp_buf_u8[s]; } else if (bmeta[0].data_type == ESPA_UINT16) { curr_pix = i * bmeta[0].nsamps; for (s = 0; s < bmeta[0].nsamps; s++, curr_pix++) file_buf_u16[curr_pix] = (uint16) tmp_buf_u8[s]; } } else { /* Read the current line from the raw binary file */ if (read_raw_binary (fp_rb[i], 1, bmeta[0].nsamps, nbytes, file_buf + (i*nbytes_line)) != SUCCESS) { sprintf (errmsg, "Reading image data from the raw binary " "file for line %d and band %d", l, i); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } } /* end for i */ /* Loop through the samples and put each band for each pixel into the output buffer */ for (s = 0; s < bmeta[0].nsamps; s++) { curr_opix = s * xml_metadata.nbands; for (i = 0; i < xml_metadata.nbands; i++, curr_opix++) { curr_ipix = i * bmeta[0].nsamps + s; if (bmeta[0].data_type == ESPA_UINT8) { ofile_buf_u8[curr_opix] = file_buf_u8[curr_ipix]; } else if (bmeta[0].data_type == ESPA_INT16) { ofile_buf_i16[curr_opix] = file_buf_i16[curr_ipix]; } else if (bmeta[0].data_type == ESPA_UINT16) { ofile_buf_u16[curr_opix] = file_buf_u16[curr_ipix]; } } } /* Write the current line of data containing all the bands to the output file */ number_elements = bmeta[0].nsamps * xml_metadata.nbands; if (fwrite (ofile_buf, nbytes, number_elements, fp_bip) != number_elements) { sprintf (errmsg, "Writing data to the BIP raw binary file for " "line %d", l); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* end for l */ /* Close the raw binary files */ for (i = 0; i < xml_metadata.nbands; i++) close_raw_binary (fp_rb[i]); close_raw_binary (fp_bip); /* Free the memory */ free (tmp_buf_u8); free (file_buf_u8); free (file_buf_i16); free (file_buf_u16); free (ofile_buf_u8); free (ofile_buf_i16); free (ofile_buf_u16); /* Create the ENVI header file for this BIP product */ if (create_envi_struct (&bmeta[0], gmeta, &envi_hdr) != SUCCESS) { sprintf (errmsg, "Creating the ENVI header structure for this file."); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Update the ENVI header (created by default for a single BSQ band) to represent that this product is a multi-band, BIP file */ envi_hdr.nbands = xml_metadata.nbands; count = snprintf (envi_hdr.interleave, sizeof (envi_hdr.interleave), "%s", "BIP"); if (count < 0 || count >= sizeof (envi_hdr.interleave)) { sprintf (errmsg, "Overflow of envi_hdr.interleave"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } for (i = 0; i < xml_metadata.nbands; i++) { count = snprintf (envi_hdr.band_names[i], sizeof (envi_hdr.band_names[i]), "%s", bmeta[i].name); if (count < 0 || count >= sizeof (envi_hdr.band_names)) { sprintf (errmsg, "Overflow of envi_hdr.band_names"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Write the ENVI header */ count = snprintf (envi_file, sizeof (envi_file), "%s", bip_file); if (count < 0 || count >= sizeof (envi_file)) { sprintf (errmsg, "Overflow of envi_file string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } cptr = strchr (envi_file, '.'); if (cptr != NULL) { /* File extension found. Replace it with the new extension */ *cptr = '\0'; strcpy (cptr, ".hdr"); } else { /* No file extension found. Just append the new extension */ strcat (envi_file, ".hdr"); } if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS) { sprintf (errmsg, "Writing the ENVI header file: %s.", envi_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Remove the source files if specified */ if (del_src) { /* Remove the image and header files for each band */ for (i = 0; i < xml_metadata.nbands; i++) { printf (" Removing %s\n", xml_metadata.band[i].file_name); if (unlink (xml_metadata.band[i].file_name) != 0) { sprintf (errmsg, "Deleting source file: %s", xml_metadata.band[i].file_name); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* .hdr file */ count = snprintf (hdr_file, sizeof (hdr_file), "%s", xml_metadata.band[i].file_name); if (count < 0 || count >= sizeof (hdr_file)) { sprintf (errmsg, "Overflow of hdr_file string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } cptr = strrchr (hdr_file, '.'); strcpy (cptr, ".hdr"); printf (" Removing %s\n", hdr_file); if (unlink (hdr_file) != 0) { sprintf (errmsg, "Deleting source file: %s", hdr_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Remove the source XML */ printf (" Removing %s\n", espa_xml_file); if (unlink (espa_xml_file) != 0) { sprintf (errmsg, "Deleting source file: %s", espa_xml_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Use the input XML file structure for the output XML file since it's the same except for the band filenames. Loop through the bands in the XML file and change the filenames to be the single output BIP filename. */ for (i = 0; i < xml_metadata.nbands; i++) { count = snprintf (bmeta[i].file_name, sizeof (bmeta[i].file_name), "%s", bip_file); if (count < 0 || count >= sizeof (bmeta[i].file_name)) { sprintf (errmsg, "Overflow of bmeta.file_name string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Create the XML file for the BIP product */ count = snprintf (xml_file, sizeof (xml_file), "%s", bip_file); if (count < 0 || count >= sizeof (xml_file)) { sprintf (errmsg, "Overflow of xml_file string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } cptr = strrchr (xml_file, '.'); if (cptr != NULL) { /* File extension found. Replace it with the new extension */ *cptr = '\0'; strcpy (cptr, "_bip.xml"); } else { /* No file extension found. Just append the new extension */ strcat (xml_file, "_bip.xml"); } /* Write the new XML file */ if (write_metadata (&xml_metadata, xml_file) != SUCCESS) { sprintf (errmsg, "Error writing updated XML for the GeoTIFF product: " "%s", xml_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Free the metadata structure */ free_metadata (&xml_metadata); /* Successful conversion */ return (SUCCESS); }
/****************************************************************************** MODULE: convert_espa_to_gtif PURPOSE: Converts the internal ESPA raw binary file to GeoTIFF file format. RETURN VALUE: Type = int Value Description ----- ----------- ERROR Error converting to GeoTIFF SUCCESS Successfully converted to GeoTIFF HISTORY: Date Programmer Reason ---------- -------------- ------------------------------------- 1/9/2014 Gail Schmidt Original development 4/2/2014 Gail Schmidt Added support for a flag to delete the source .img and .hdr files 4/3/2014 Gail Schmidt Remove the .xml file as well if source files are specified to be deleted 4/30/2014 Gail Schmidt Remove the .tif.aux.xml files that were created by GDAL in the conversion to GeoTIFF NOTES: 1. The GDAL tools will be used for converting the raw binary (ENVI format) files to GeoTIFF. 2. An associated .tfw (ESRI world file) will be generated for each GeoTIFF file. ******************************************************************************/ int convert_espa_to_gtif ( char *espa_xml_file, /* I: input ESPA XML metadata filename */ char *gtif_file, /* I: base output GeoTIFF filename */ bool del_src /* I: should the source files be removed after conversion? */ ) { char FUNC_NAME[] = "convert_espa_to_gtif"; /* function name */ char errmsg[STR_SIZE]; /* error message */ char gdal_cmd[STR_SIZE]; /* command string for GDAL call */ char gtif_band[STR_SIZE]; /* name of the GeoTIFF file for this band */ char hdr_file[STR_SIZE]; /* name of the header file for this band */ char xml_file[STR_SIZE]; /* new XML file for the GeoTIFF product */ char tmpfile[STR_SIZE]; /* filename of file.tif.aux.xml */ char *cptr = NULL; /* pointer to empty space in the band name */ int i; /* looping variable for each band */ int count; /* number of chars copied in snprintf */ Espa_internal_meta_t xml_metadata; /* XML metadata structure to be populated by reading the XML metadata file */ /* Validate the input metadata file */ if (validate_xml_file (espa_xml_file) != SUCCESS) { /* Error messages already written */ return (ERROR); } /* Initialize the metadata structure */ init_metadata_struct (&xml_metadata); /* Parse the metadata file into our internal metadata structure; also allocates space as needed for various pointers in the global and band metadata */ if (parse_metadata (espa_xml_file, &xml_metadata) != SUCCESS) { /* Error messages already written */ return (ERROR); } /* Loop through the bands in the XML file and convert them to GeoTIFF. The filenames will have the GeoTIFF base name followed by _ and the band name of each band in the XML file. Blank spaced in the band name will be replaced with underscores. */ for (i = 0; i < xml_metadata.nbands; i++) { /* Determine the output GeoTIFF band name */ count = snprintf (gtif_band, sizeof (gtif_band), "%s_%s.tif", gtif_file, xml_metadata.band[i].name); if (count < 0 || count >= sizeof (gtif_band)) { sprintf (errmsg, "Overflow of gtif_file string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Loop through this filename and replace any occurances of blank spaces with underscores */ while ((cptr = strchr (gtif_band, ' ')) != NULL) *cptr = '_'; /* Convert the files */ printf ("Converting %s to %s\n", xml_metadata.band[i].file_name, gtif_band); count = snprintf (gdal_cmd, sizeof (gdal_cmd), "gdal_translate -of Gtiff -a_nodata %ld -co \"TFW=YES\" -q %s %s", xml_metadata.band[i].fill_value, xml_metadata.band[i].file_name, gtif_band); if (count < 0 || count >= sizeof (gdal_cmd)) { sprintf (errmsg, "Overflow of gdal_cmd string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } if (system (gdal_cmd) == -1) { sprintf (errmsg, "Running gdal_translate: %s", gdal_cmd); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Remove the {gtif_name}.tif.aux.xml file since it's not needed and clutters the results. Don't worry about testing the unlink results. If it doesn't unlink it's not fatal. */ count = snprintf (tmpfile, sizeof (tmpfile), "%s.aux.xml", gtif_band); if (count < 0 || count >= sizeof (tmpfile)) { sprintf (errmsg, "Overflow of tmpfile string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } unlink (tmpfile); /* Remove the source file if specified */ if (del_src) { /* .img file */ printf (" Removing %s\n", xml_metadata.band[i].file_name); if (unlink (xml_metadata.band[i].file_name) != 0) { sprintf (errmsg, "Deleting source file: %s", xml_metadata.band[i].file_name); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* .hdr file */ count = snprintf (hdr_file, sizeof (hdr_file), "%s", xml_metadata.band[i].file_name); if (count < 0 || count >= sizeof (hdr_file)) { sprintf (errmsg, "Overflow of hdr_file string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } cptr = strrchr (hdr_file, '.'); strcpy (cptr, ".hdr"); printf (" Removing %s\n", hdr_file); if (unlink (hdr_file) != 0) { sprintf (errmsg, "Deleting source file: %s", hdr_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Update the XML file to use the new GeoTIFF band name */ strcpy (xml_metadata.band[i].file_name, gtif_band); } /* Remove the source XML if specified */ if (del_src) { printf (" Removing %s\n", espa_xml_file); if (unlink (espa_xml_file) != 0) { sprintf (errmsg, "Deleting source file: %s", espa_xml_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } } /* Create the XML file for the GeoTIFF product */ count = snprintf (xml_file, sizeof (xml_file), "%s_gtif.xml", gtif_file); if (count < 0 || count >= sizeof (xml_file)) { sprintf (errmsg, "Overflow of xml_file string"); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Write the new XML file containing the GeoTIFF band names */ if (write_metadata (&xml_metadata, xml_file) != SUCCESS) { sprintf (errmsg, "Error writing updated XML for the GeoTIFF product: " "%s", xml_file); error_handler (true, FUNC_NAME, errmsg); return (ERROR); } /* Free the metadata structure */ free_metadata (&xml_metadata); /* Successful conversion */ return (SUCCESS); }
static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; AVCodecContext *enc = s->streams[pkt->stream_index]->codec; FLVContext *flv = s->priv_data; FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data; unsigned ts; int size = pkt->size; uint8_t *data = NULL; int flags = -1, flags_size, ret; if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A || enc->codec_id == AV_CODEC_ID_VP6 || enc->codec_id == AV_CODEC_ID_AAC) flags_size = 2; else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) flags_size = 5; else flags_size = 1; if (flv->delay == AV_NOPTS_VALUE) flv->delay = -pkt->dts; if (pkt->dts < -flv->delay) { av_log(s, AV_LOG_WARNING, "Packets are not in the proper order with respect to DTS\n"); return AVERROR(EINVAL); } ts = pkt->dts + flv->delay; // add delay to force positive dts if (s->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) { write_metadata(s, ts); s->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED; } switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: avio_w8(pb, FLV_TAG_TYPE_VIDEO); flags = enc->codec_tag; if (flags == 0) { av_log(s, AV_LOG_ERROR, "Video codec '%s' is not compatible with FLV\n", avcodec_get_name(enc->codec_id)); return AVERROR(EINVAL); } flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER; break; case AVMEDIA_TYPE_AUDIO: flags = get_audio_flags(s, enc); av_assert0(size); avio_w8(pb, FLV_TAG_TYPE_AUDIO); break; case AVMEDIA_TYPE_SUBTITLE: case AVMEDIA_TYPE_DATA: avio_w8(pb, FLV_TAG_TYPE_META); break; default: return AVERROR(EINVAL); } if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { /* check if extradata looks like mp4 formated */ if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0) return ret; } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { if (!s->streams[pkt->stream_index]->nb_frames) { av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: " "use the audio bitstream filter 'aac_adtstoasc' to fix it " "('-bsf:a aac_adtstoasc' option with ffmpeg)\n"); return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_WARNING, "aac bitstream error\n"); } /* check Speex packet duration */ if (enc->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160) av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than " "8 frames per packet. Adobe Flash " "Player cannot handle this!\n"); if (sc->last_ts < ts) sc->last_ts = ts; if (size + flags_size >= 1<<24) { av_log(s, AV_LOG_ERROR, "Too large packet with size %u >= %u\n", size + flags_size, 1<<24); return AVERROR(EINVAL); } avio_wb24(pb, size + flags_size); avio_wb24(pb, ts & 0xFFFFFF); avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_ avio_wb24(pb, flv->reserved); if (enc->codec_type == AVMEDIA_TYPE_DATA || enc->codec_type == AVMEDIA_TYPE_SUBTITLE ) { int data_size; int64_t metadata_size_pos = avio_tell(pb); if (enc->codec_id == AV_CODEC_ID_TEXT) { // legacy FFmpeg magic? avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, "onTextData"); avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); avio_wb32(pb, 2); put_amf_string(pb, "type"); avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, "Text"); put_amf_string(pb, "text"); avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, pkt->data); put_amf_string(pb, ""); avio_w8(pb, AMF_END_OF_OBJECT); } else { // just pass the metadata through avio_write(pb, data ? data : pkt->data, size); } /* write total size of tag */ data_size = avio_tell(pb) - metadata_size_pos; avio_seek(pb, metadata_size_pos - 10, SEEK_SET); avio_wb24(pb, data_size); avio_seek(pb, data_size + 10 - 3, SEEK_CUR); avio_wb32(pb, data_size + 11); } else { av_assert1(flags>=0); avio_w8(pb,flags); if (enc->codec_id == AV_CODEC_ID_VP6) avio_w8(pb,0); if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A) { if (enc->extradata_size) avio_w8(pb, enc->extradata[0]); else avio_w8(pb, ((FFALIGN(enc->width, 16) - enc->width) << 4) | (FFALIGN(enc->height, 16) - enc->height)); } else if (enc->codec_id == AV_CODEC_ID_AAC) avio_w8(pb, 1); // AAC raw else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { avio_w8(pb, 1); // AVC NALU avio_wb24(pb, pkt->pts - pkt->dts); } avio_write(pb, data ? data : pkt->data, size); avio_wb32(pb, size + flags_size + 11); // previous tag size flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration); } av_free(data); return pb->error; }
static int flv_write_header(AVFormatContext *s) { int i; AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; int64_t data_size; for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; FLVStreamContext *sc; switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: if (s->streams[i]->avg_frame_rate.den && s->streams[i]->avg_frame_rate.num) { flv->framerate = av_q2d(s->streams[i]->avg_frame_rate); } if (flv->video_enc) { av_log(s, AV_LOG_ERROR, "at most one video stream is supported in flv\n"); return AVERROR(EINVAL); } flv->video_enc = enc; if (enc->codec_tag == 0) { av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n", avcodec_get_name(enc->codec_id), i); return AVERROR(EINVAL); } if (enc->codec_id == AV_CODEC_ID_MPEG4 || enc->codec_id == AV_CODEC_ID_H263) { int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL; av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING, "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id)); if (error) { av_log(s, AV_LOG_ERROR, "use vstrict=-1 / -strict -1 to use it anyway.\n"); return AVERROR(EINVAL); } } else if (enc->codec_id == AV_CODEC_ID_VP6) { av_log(s, AV_LOG_WARNING, "Muxing VP6 in flv will produce flipped video on playback.\n"); } break; case AVMEDIA_TYPE_AUDIO: if (flv->audio_enc) { av_log(s, AV_LOG_ERROR, "at most one audio stream is supported in flv\n"); return AVERROR(EINVAL); } flv->audio_enc = enc; if (get_audio_flags(s, enc) < 0) return AVERROR_INVALIDDATA; if (enc->codec_id == AV_CODEC_ID_PCM_S16BE) av_log(s, AV_LOG_WARNING, "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n"); break; case AVMEDIA_TYPE_DATA: if (enc->codec_id != AV_CODEC_ID_TEXT && enc->codec_id != AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n", avcodec_get_name(enc->codec_id), i); return AVERROR_INVALIDDATA; } flv->data_enc = enc; break; case AVMEDIA_TYPE_SUBTITLE: if (enc->codec_id != AV_CODEC_ID_TEXT) { av_log(s, AV_LOG_ERROR, "Subtitle codec '%s' for stream %d is not compatible with FLV\n", avcodec_get_name(enc->codec_id), i); return AVERROR_INVALIDDATA; } flv->data_enc = enc; break; default: av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n", av_get_media_type_string(enc->codec_type), i); return AVERROR(EINVAL); } avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ sc = av_mallocz(sizeof(FLVStreamContext)); if (!sc) return AVERROR(ENOMEM); s->streams[i]->priv_data = sc; sc->last_ts = -1; } flv->delay = AV_NOPTS_VALUE; avio_write(pb, "FLV", 3); avio_w8(pb, 1); avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!flv->audio_enc + FLV_HEADER_FLAG_HASVIDEO * !!flv->video_enc); avio_wb32(pb, 9); avio_wb32(pb, 0); for (i = 0; i < s->nb_streams; i++) if (s->streams[i]->codec->codec_tag == 5) { avio_w8(pb, 8); // message type avio_wb24(pb, 0); // include flags avio_wb24(pb, 0); // time stamp avio_wb32(pb, 0); // reserved avio_wb32(pb, 11); // size flv->reserved = 5; } write_metadata(s, 0); for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { int64_t pos; avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); avio_wb24(pb, 0); // size patched later avio_wb24(pb, 0); // ts avio_w8(pb, 0); // ts ext avio_wb24(pb, 0); // streamid pos = avio_tell(pb); if (enc->codec_id == AV_CODEC_ID_AAC) { avio_w8(pb, get_audio_flags(s, enc)); avio_w8(pb, 0); // AAC sequence header avio_write(pb, enc->extradata, enc->extradata_size); } else { avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags avio_w8(pb, 0); // AVC sequence header avio_wb24(pb, 0); // composition time ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); } data_size = avio_tell(pb) - pos; avio_seek(pb, -data_size - 10, SEEK_CUR); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); // previous tag size } } return 0; }
static gboolean gst_wavenc_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean res = TRUE; GstWavEnc *wavenc; GstToc *toc; wavenc = GST_WAVENC (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); gst_wavenc_sink_setcaps (pad, caps); /* have our own src caps */ gst_event_unref (event); break; } case GST_EVENT_EOS:{ GST_DEBUG_OBJECT (wavenc, "got EOS"); if (!wavenc->toc) { GST_DEBUG_OBJECT (wavenc, "have no toc, checking toc_setter"); wavenc->toc = gst_toc_setter_get_toc (GST_TOC_SETTER (wavenc)); } if (wavenc->toc) { GST_DEBUG_OBJECT (wavenc, "have toc"); gst_wavenc_write_toc (wavenc); } #if 0 /* Write our metadata if we have any */ if (wavenc->metadata) { write_metadata (wavenc); write_cues (wavenc); write_labels (wavenc); } #endif /* write header with correct length values */ gst_wavenc_push_header (wavenc, wavenc->length); /* we're done with this file */ wavenc->finished_properly = TRUE; /* and forward the EOS event */ res = gst_pad_event_default (pad, parent, event); break; } case GST_EVENT_SEGMENT: /* Just drop it, it's probably in TIME format * anyway. We'll send our own newsegment event */ gst_event_unref (event); break; case GST_EVENT_TOC: gst_event_parse_toc (event, &toc, NULL); if (toc) { if (wavenc->toc != toc) { if (wavenc->toc) gst_toc_unref (wavenc->toc); wavenc->toc = toc; } else { gst_toc_unref (toc); } } res = gst_pad_event_default (pad, parent, event); break; default: res = gst_pad_event_default (pad, parent, event); break; } return res; }
void encode_file(char *file, int nativeBlockNum, int parityBlockNum) { int chunkSize = 1; int totalSize; FILE *fp_in; FILE *fp_out; if( ( fp_in = fopen(file,"rb") ) == NULL ) { printf("Can not open source file!\n"); exit(0); } fseek(fp_in, 0L, SEEK_END); //ftell() get the total size of the file totalSize = ftell(fp_in); chunkSize = (totalSize / nativeBlockNum) + ( totalSize%nativeBlockNum != 0 ); // chunkSize = (ftell(fp_in) / nativeBlockNum) + ( ftell(fp_in)%nativeBlockNum != 0 ); // chunkSize = (int) (ceil( (long double) (ftell(fp_in) / nativeBlockNum)) ); uint8_t *dataBuf; //host uint8_t *codeBuf; //host int dataSize = nativeBlockNum*chunkSize*sizeof(uint8_t); int codeSize = parityBlockNum*chunkSize*sizeof(uint8_t); dataBuf = (uint8_t*) malloc( nativeBlockNum*chunkSize*sizeof(uint8_t) ); memset(dataBuf, 0, dataSize); codeBuf = (uint8_t*) malloc( parityBlockNum*chunkSize*sizeof(uint8_t) ); memset(codeBuf, 0, codeSize); int i; for(i=0; i<nativeBlockNum; i++) { if( fseek( fp_in, i*chunkSize, SEEK_SET ) == -1 ) { printf("fseek error!\n"); exit(0); } if( fread( dataBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_in ) == EOF ) { printf("fread error!\n"); exit(0); } } fclose(fp_in); struct timespec start, end; double totalTime; clock_gettime(CLOCK_REALTIME,&start); // // setup table for GF(2^8) // setup_tables(8); uint8_t *encodingMatrix; encodingMatrix = (uint8_t*) malloc( parityBlockNum*nativeBlockNum*sizeof(uint8_t) ); gen_encoding_matrix(encodingMatrix, parityBlockNum, nativeBlockNum); write_metadata(totalSize, parityBlockNum, nativeBlockNum, encodingMatrix); encode_chunk(dataBuf, encodingMatrix, codeBuf, nativeBlockNum, parityBlockNum, chunkSize); // matrix_mul(encodingMatrix, dataBuf, codeBuf, parityBlockNum, nativeBlockNum, chunkSize); /* //int i; int j; int k; int n=parityBlockNum; int p=nativeBlockNum; int m=chunkSize; for(i=0; i<n; i++) { for(j=0; j<m; j++) { codeBuf[i*m+j] = 0; for(k=0; k<p; k++) { // C[i*m+j] = gf_add(C[i*m+j], gf_mul(A[i*p+k],B[k*m+j])); codeBuf[i*m+j] ^= gf_mul(encodingMatrix[i*p+k],dataBuf[k*m+j]); } } } */ clock_gettime(CLOCK_REALTIME,&end); totalTime = (double)(end.tv_sec-start.tv_sec)*1000+(double)(end.tv_nsec-start.tv_nsec)/(double)1000000L; printf("Total CPU encoding time: %fms\n", totalTime); char output_file_name[100]; for(i=0; i<nativeBlockNum; i++) { sprintf(output_file_name, "_%d_", i); strcat(output_file_name, file); if( ( fp_out = fopen(output_file_name, "wb") ) == NULL ) { printf("Can not open source file!\n"); exit(0); } if( fwrite(dataBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_out ) != sizeof(uint8_t)*chunkSize ) { printf("fwrite error!\n"); exit(0); } fclose(fp_out); } for(i=0; i<parityBlockNum; i++) { sprintf(output_file_name, "_%d_", i+nativeBlockNum); strcat(output_file_name, file); if( ( fp_out = fopen(output_file_name, "wb") ) == NULL ) { printf("Can not open source file!\n"); exit(0); } if( fwrite(codeBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_out ) != sizeof(uint8_t)*chunkSize ) { printf("fwrite error!\n"); exit(0); } fclose(fp_out); } free(dataBuf); free(codeBuf); free(encodingMatrix); }