Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
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);
}
Пример #6
0
Файл: instr.c Проект: parrot/m1
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");  

}
Пример #7
0
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;	
}
Пример #9
0
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));
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
Файл: mkfs.c Проект: colyli/cmfs
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);
	}
}
Пример #13
0
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);
}
Пример #14
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;
}
Пример #15
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;
}
Пример #16
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);
}
Пример #17
0
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);
}
Пример #18
0
/*!
 * \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;
}
Пример #19
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;
}
Пример #20
0
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);
}
Пример #21
0
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");
}
Пример #22
0
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;
}
Пример #24
0
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);
}
Пример #27
0
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;
}
Пример #28
0
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;
}
Пример #29
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;
}
Пример #30
0
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);

}