Beispiel #1
0
void
write_sff_read_header(FILE *fp, sff_read_header *rh) {
	int header_size;
	char *name;
	uint16_t header_len         = be16toh(rh->header_len);
	uint16_t name_len           = be16toh(rh->name_len);
	uint32_t nbases             = be32toh(rh->nbases);
    uint16_t clip_qual_left     = be16toh(rh->clip_qual_left);
    uint16_t clip_qual_right    = be16toh(rh->clip_qual_right);
    uint16_t clip_adapter_left  = be16toh(rh->clip_adapter_left);
    uint16_t clip_adapter_right = be16toh(rh->clip_adapter_right);
    name = rh->name;
    fwrite(&header_len        , sizeof(uint16_t), 1, fp);
    fwrite(&name_len          , sizeof(uint16_t), 1, fp);
    fwrite(&nbases            , sizeof(uint32_t), 1, fp);
    fwrite(&clip_qual_left    , sizeof(uint16_t), 1, fp);
    fwrite(&clip_qual_right   , sizeof(uint16_t), 1, fp);
    fwrite(&clip_adapter_left , sizeof(uint16_t), 1, fp);
    fwrite(&clip_adapter_right, sizeof(uint16_t), 1, fp);
    fwrite(name, sizeof(char), rh->name_len, fp);
    /* the section should be a multiple of 8-bytes, if not,
       it is zero-byte padded to make it so */
    header_size = sizeof(rh->header_len)
                  + sizeof(rh->name_len)
                  + sizeof(rh->nbases)
                  + sizeof(rh->clip_qual_left)
                  + sizeof(rh->clip_qual_right)
                  + sizeof(rh->clip_adapter_left)
                  + sizeof(rh->clip_adapter_right)
                  + (sizeof(char) * rh->name_len);
    if ( !(header_size % PADDING_SIZE == 0) ) {
        write_padding(fp, header_size);
    }
}
Beispiel #2
0
static void write_finalize( filter_t *p_filter, uint16_t i_data_type,
                            uint8_t i_length_mul )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    assert( p_sys->p_out_buf != NULL );
    uint8_t *p_out = p_sys->p_out_buf->p_buffer;

    /* S/PDIF header */
    if( i_data_type != 0 )
    {
        assert( p_sys->i_out_offset > SPDIF_HEADER_SIZE );
        assert( i_length_mul == 1 || i_length_mul == 8 );

        set_16( p_filter, &p_out[0], 0xf872 ); /* syncword 1 */
        set_16( p_filter, &p_out[2], 0x4e1f ); /* syncword 2 */
        set_16( p_filter, &p_out[4], i_data_type ); /* data type */
        /* length in bits or bytes */
        set_16( p_filter, &p_out[6],
                  ( p_sys->i_out_offset - SPDIF_HEADER_SIZE ) * i_length_mul );
    }

    /* 0 padding */
    if( p_sys->i_out_offset < p_sys->p_out_buf->i_buffer )
        write_padding( p_filter,
                       p_sys->p_out_buf->i_buffer - p_sys->i_out_offset );
}
Beispiel #3
0
static ptrdiff_t
write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags)
{
  uint8_t *cur = buf;
  uint32_t iseq_no;

  cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
  cur += write_padding(cur);
  switch (flags & DUMP_ENDIAN_NAT) {
  case DUMP_ENDIAN_BIG:
    if (bigendian_p()) goto native;
    for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
      cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
    }
    break;
  case DUMP_ENDIAN_LIL:
    if (!bigendian_p()) goto native;
    for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
      cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */
    }
    break;

  native:
  case DUMP_ENDIAN_NAT:
    memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code));
    cur += irep->ilen * sizeof(mrb_code);
    break;
  }

  return cur - buf;
}
Beispiel #4
0
int main(int argc, const char* argv[]) 
{
    if(argc <= 2) 
    {
        printf("\nADF trackloader creator\n\n");
        printf("   Usage: %s <output adf> <bootblock> [<files>]\n\n", argv[0]);
        exit(0);
    }

    FILE *adf_file = fopen(argv[1], "wb");

    if(!adf_file)
    {
        fputs("ADF file error", stderr); 
        exit(0);
    }

    unsigned int file_size = 0;

    file_size += write_bootblock(adf_file, argv[2]);

    for(int i = 3; i < argc; i++)
    {
        file_size += write_file(adf_file, argv[i]);
    }

    if(file_size < DISK_SIZE)
    {
        write_padding(adf_file, file_size);
    }
}
Beispiel #5
0
void write_print(michet_t *michet, char *text_to_print, size_t len)
{
  uint8_t instruction;

  // mov edx, len
  write_instruction(michet->fp, MOV+EDX);
  write_instruction(michet->fp, len);
  write_padding(michet->fp);

  // mov ecx, 0xA0
  write_instruction(michet->fp, MOV+ECX);
  write_instruction(michet->fp, 0xA0); // 0xA0 is the address where the string starts

  // Unknown bits
  write_instruction(michet->fp, 0x90);
  write_instruction(michet->fp, 0x04);
  write_instruction(michet->fp, 0x08);

  // mov ebx, 1
  write_instruction(michet->fp, MOV+EBX);
  write_instruction(michet->fp, 0x01);
  write_padding(michet->fp);

  // mov eax, 4
  write_instruction(michet->fp, MOV+EAX);
  write_instruction(michet->fp, 0x04);
  write_padding(michet->fp);

  // int 0x80
  write_instruction(michet->fp, INT);
  write_instruction(michet->fp, 0x80);

  // mov eax, 1
  write_instruction(michet->fp, MOV+EAX);
  write_instruction(michet->fp, 0x01);
  write_padding(michet->fp);

  // int 0x80
  write_instruction(michet->fp, INT);
  write_instruction(michet->fp, 0x80);
  write_padding(michet->fp);

  fwrite(text_to_print, len, 1, michet->fp);

  fflush(michet->fp);

}
Beispiel #6
0
/* Adapted from libavformat/spdifenc.c: */
static int write_buffer_dtshd( filter_t *p_filter, block_t *p_in_buf )
{
    static const char p_dtshd_start_code[10] = {
        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe
    };
    static const size_t i_dtshd_start_code = sizeof( p_dtshd_start_code );

    filter_sys_t *p_sys = p_filter->p_sys;
    vlc_dts_header_t core;
    if( vlc_dts_header_Parse( &core, p_in_buf->p_buffer,
                              p_in_buf->i_buffer ) != VLC_SUCCESS )
        return SPDIF_ERROR;
    unsigned i_period = p_filter->fmt_out.audio.i_rate
                      * core.i_frame_length / core.i_rate;

    int i_subtype = dtshd_get_subtype( i_period );
    if( i_subtype == -1 )
        return SPDIF_ERROR;

    size_t i_in_size = i_dtshd_start_code + 2 + p_in_buf->i_buffer;
    size_t i_out_size = i_period * 4;
    uint16_t i_data_type = IEC61937_DTSHD | i_subtype << 8;

    if( p_filter->p_sys->dtshd.b_skip
     || i_in_size + SPDIF_HEADER_SIZE > i_out_size )
    {
        /* The bitrate is too high, pass only the core part */
        p_in_buf->i_buffer = core.i_frame_size;
        i_in_size = i_dtshd_start_code + 2 + p_in_buf->i_buffer;
        if( i_in_size + SPDIF_HEADER_SIZE > i_out_size )
            return SPDIF_ERROR;

        /* Don't try to send substreams anymore. That way, we avoid to switch
         * back and forth between DTD and DTS-HD */
        p_filter->p_sys->dtshd.b_skip = true;
    }

    if( write_init( p_filter, p_in_buf, i_out_size,
                    i_out_size / p_filter->fmt_out.audio.i_bytes_per_frame ) )
        return SPDIF_ERROR;

    write_data( p_filter, p_dtshd_start_code, i_dtshd_start_code, true );
    write_16( p_filter, p_in_buf->i_buffer );
    write_buffer( p_filter, p_in_buf );

    /* Align so that (length_code & 0xf) == 0x8. This is reportedly needed
     * with some receivers, but the exact requirement is unconfirmed. */
#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
    size_t i_align = ALIGN( i_in_size + 0x8, 0x10 ) - 0x8;
#undef ALIGN
    if( i_align > i_in_size && i_align - i_in_size
        <= p_sys->p_out_buf->i_buffer - p_sys->i_out_offset )
        write_padding( p_filter, i_align - i_in_size );

    write_finalize( p_filter, i_data_type, 1 /* in bytes */ );
    return SPDIF_SUCCESS;
}
Beispiel #7
0
/* CPIO voodoo. */
static void
cpio_append_trailer (void)
{
  struct stat statbuf;
  memset (&statbuf, 0, sizeof statbuf);
  statbuf.st_nlink = 1;
  cpio_append_stat ("TRAILER!!!", &statbuf);

  /* CPIO seems to pad up to the next block boundary, ie. up to
   * the next 512 bytes.
   */
  write_padding (((out_offset + 511) & ~511) - out_offset);
  assert ((out_offset & 511) == 0);
}
Beispiel #8
0
gboolean
ostree_write_variant_with_size (GOutputStream      *output,
                                GVariant           *variant,
                                guint64             alignment_offset,
                                gsize              *out_bytes_written,
                                GChecksum          *checksum,
                                GCancellable       *cancellable,
                                GError            **error)
{
  gboolean ret = FALSE;
  guint64 variant_size;
  guint32 variant_size_u32_be;
  gsize bytes_written;
  gsize ret_bytes_written = 0;

  /* Write variant size */
  variant_size = g_variant_get_size (variant);
  g_assert (variant_size < G_MAXUINT32);
  variant_size_u32_be = GUINT32_TO_BE((guint32) variant_size);

  bytes_written = 0;
  if (!ot_gio_write_update_checksum (output, &variant_size_u32_be, 4,
                                     &bytes_written, checksum,
                                     cancellable, error))
    goto out;
  ret_bytes_written += bytes_written;
  alignment_offset += bytes_written;

  bytes_written = 0;
  /* Pad to offset of 8, write variant */
  if (!write_padding (output, 8, alignment_offset, &bytes_written, checksum,
                      cancellable, error))
    goto out;
  ret_bytes_written += bytes_written;

  bytes_written = 0;
  if (!ot_gio_write_update_checksum (output, g_variant_get_data (variant),
                                     variant_size, &bytes_written, checksum,
                                     cancellable, error))
    goto out;
  ret_bytes_written += bytes_written;

  ret = TRUE;
  if (out_bytes_written)
    *out_bytes_written = ret_bytes_written;
 out:
  return ret;
}
Beispiel #9
0
void
write_sff_read_data(FILE *fp, sff_read_data *rd, uint16_t nflows, uint32_t nbases) {
    int data_size;
    int i;
    /* read from the sff file and assign to sff_read_data */
    fwrite(rd->flowgram, sizeof(uint16_t), (size_t) nflows, fp);
    fwrite(rd->flow_index, sizeof(uint8_t), (size_t) nbases, fp);
    fwrite(rd->bases, sizeof(char), (size_t) nbases, fp);
    fwrite(rd->quality, sizeof(uint8_t), (size_t) nbases, fp);
    /* the section should be a multiple of 8-bytes, if not,
       it is zero-byte padded to make it so */
    data_size = (sizeof(uint16_t) * nflows)    // flowgram size
                + (sizeof(uint8_t) * nbases)   // flow_index size
                + (sizeof(char) * nbases)      // bases size
                + (sizeof(uint8_t) * nbases);  // quality size
    if ( !(data_size % PADDING_SIZE == 0) ) {
        write_padding(fp, data_size);
    }
}
Beispiel #10
0
static int init() {
	struct resource *p;
	int err = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
	resource_size_t p_last = -1;
#else
	__PTRDIFF_TYPE__ p_last = -1;
#endif

	DBG("Initilizing Dump...");

	if((err = setup())) {
		DBG("Setup Error");
		cleanup();
		return err;
	}

	for (p = iomem_resource.child; p ; p = p->sibling) {
		if (strcmp(p->name, LIME_RAMSTR))
			continue;

		if (mode == LIME_MODE_LIME && (err = write_lime_header(p))) {
			DBG("Error writing header 0x%lx - 0x%lx", (long) p->start, (long) p->end);
			break;
		} else if (mode == LIME_MODE_PADDED && (err = write_padding((size_t) ((p->start - 1) - p_last)))) {
			DBG("Error writing padding 0x%lx - 0x%lx", (long) p_last, (long) p->start - 1);
			break;
		}

		if ((err = write_range(p))) {
			DBG("Error writing range 0x%lx - 0x%lx", (long) p->start, (long) p->end);
			break;
		}

		p_last = p->end;
	}
	

	cleanup();

	return err;
}
Beispiel #11
0
/* F U N C T I O N S *********************************************************/
void
write_sff_common_header(FILE *fp, sff_common_header *h) {
    int header_size;
    uint32_t magic        = be32toh(h->magic);
    uint64_t index_offset = be64toh(h->index_offset);
    uint32_t index_len    = be32toh(h->index_len);
    uint32_t nreads       = be32toh(h->nreads);
    uint16_t header_len   = be16toh(h->header_len);
    uint16_t key_len      = be16toh(h->key_len);
    uint16_t flow_len     = be16toh(h->flow_len);
    fwrite(&magic          , sizeof(uint32_t), 1, fp);
    fwrite(&(h->version)   , sizeof(char)    , 4, fp);
    fwrite(&index_offset   , sizeof(uint64_t), 1, fp);
    fwrite(&index_len      , sizeof(uint32_t), 1, fp);
    fwrite(&nreads         , sizeof(uint32_t), 1, fp);
    fwrite(&header_len     , sizeof(uint16_t), 1, fp);
    fwrite(&key_len        , sizeof(uint16_t), 1, fp);
    fwrite(&flow_len       , sizeof(uint16_t), 1, fp);
    fwrite(&(h->flowgram_format), sizeof(uint8_t) , 1, fp);
    fwrite(h->flow, sizeof(char), h->flow_len, fp);
    fwrite(h->key , sizeof(char), h->key_len , fp);

    /* the common header section should be a multiple of 8-bytes
       if the header is not, it is zero-byte padded to make it so */
    header_size = sizeof(h->magic)
                  + sizeof(*(h->version))*4
                  + sizeof(h->index_offset)
                  + sizeof(h->index_len)
                  + sizeof(h->nreads)
                  + sizeof(h->header_len)
                  + sizeof(h->key_len)
                  + sizeof(h->flow_len)
                  + sizeof(h->flowgram_format)
                  + (sizeof(char) * h->flow_len)
                  + (sizeof(char) * h->key_len);
    if ( !(header_size % PADDING_SIZE == 0) ) {
        write_padding(fp, header_size);
    }
}
Beispiel #12
0
static int write_range(struct resource * res) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
	resource_size_t i, is;
#else
	__PTRDIFF_TYPE__ i, is;
#endif
	struct page * p;
	void * v;
	
	int s;

	for (i = res->start; i <= res->end; i += is) {

		p = pfn_to_page((i) >> PAGE_SHIFT);
        
        is = min((size_t) PAGE_SIZE, (size_t) (res->end - i + 1));

        if (is < PAGE_SIZE) {
        	// We can't map partial pages and 
        	// the linux kernel doesn't use them anyway
        	DBG("Padding partial page: vaddr %p size: %lu", (void *) i, is);
        	write_padding(is);
        } else {
			v = kmap(p);
			s = write_vaddr(v, is);
			kunmap(p);

			if (s != is) {
				DBG("Error writing page: vaddr %p ret: %d", v, s);
				return (int) s;
			}
		}
	}

	return 0;
}
Beispiel #13
0
static void
cpio_append_stat (const char *filename, const struct stat *statbuf)
{
  const char *orig_filename = filename;

  if (*filename == '/')
    filename++;
  if (*filename == '\0')
    filename = ".";

  if (verbose >= 2)
    fprintf (stderr, "cpio_append_stat %s 0%o -> %d\n",
             orig_filename, statbuf->st_mode, out_fd);

  /* Regular files and symlinks are the only ones that have a "body"
   * in this cpio entry.
   */
  int has_body = S_ISREG (statbuf->st_mode) || S_ISLNK (statbuf->st_mode);

  size_t len = strlen (filename) + 1;

  char header[CPIO_HEADER_LEN + 1];
  snprintf (header, sizeof header,
            "070701"            /* magic */
            "%08X"              /* inode */
            "%08X"              /* mode */
            "%08X" "%08X"       /* uid, gid */
            "%08X"              /* nlink */
            "%08X"              /* mtime */
            "%08X"              /* file length */
            "%08X" "%08X"       /* device holding file major, minor */
            "%08X" "%08X"       /* for specials, device major, minor */
            "%08X"              /* name length (including \0 byte) */
            "%08X",             /* checksum (not used by the kernel) */
            (unsigned) statbuf->st_ino, statbuf->st_mode,
            statbuf->st_uid, statbuf->st_gid,
            (unsigned) statbuf->st_nlink, (unsigned) statbuf->st_mtime,
            has_body ? (unsigned) statbuf->st_size : 0,
            major (statbuf->st_dev), minor (statbuf->st_dev),
            major (statbuf->st_rdev), minor (statbuf->st_rdev),
            (unsigned) len, 0);

  /* Write the header. */
  write_to_fd (header, CPIO_HEADER_LEN);

  /* Follow with the filename, and pad it. */
  write_to_fd (filename, len);
  size_t padding_len = PADDING (CPIO_HEADER_LEN + len);
  write_padding (padding_len);

  /* Follow with the file or symlink content, and pad it. */
  if (has_body) {
    if (S_ISREG (statbuf->st_mode))
      write_file_len_to_fd (orig_filename, statbuf->st_size);
    else if (S_ISLNK (statbuf->st_mode)) {
      char tmp[PATH_MAX];
      if (readlink (orig_filename, tmp, sizeof tmp) == -1)
        error (EXIT_FAILURE, errno, "readlink: %s", orig_filename);
      write_to_fd (tmp, statbuf->st_size);
    }

    padding_len = PADDING (statbuf->st_size);
    write_padding (padding_len);
  }
}
Beispiel #14
0
int main(int argc, char **argv)
{
    boot_img_hdr hdr;

    char *kernel_fn = 0;
    void *kernel_data = 0;
    char *ramdisk_fn = 0;
    void *ramdisk_data = 0;
    char *second_fn = 0;
    void *second_data = 0;
    char *cmdline = "";
    char *bootimg = 0;
    char *board = "";
    unsigned pagesize = 2048;
    unsigned saddr = 0;
    int fd;
    SHA_CTX ctx;
    uint8_t* sha;

    argc--;
    argv++;

    memset(&hdr, 0, sizeof(hdr));

        /* default load addresses */
    hdr.kernel_addr =  0x10008000;
    hdr.ramdisk_addr = 0x11000000;
    hdr.second_addr =  0x10F00000;
    hdr.tags_addr =    0x10000100;

    hdr.page_size = pagesize;

    while(argc > 0){
        char *arg = argv[0];
        char *val = argv[1];
        if(argc < 2) {
            return usage();
        }
        argc -= 2;
        argv += 2;
        if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
            bootimg = val;
        } else if(!strcmp(arg, "--kernel")) {
            kernel_fn = val;
        } else if(!strcmp(arg, "--ramdisk")) {
            ramdisk_fn = val;
        } else if(!strcmp(arg, "--second")) {
            second_fn = val;
        } else if(!strcmp(arg, "--cmdline")) {
            cmdline = val;
        } else if(!strcmp(arg, "--base")) {
            unsigned base = strtoul(val, 0, 16);
            hdr.kernel_addr =  base + 0x00008000;
            hdr.ramdisk_addr = base + 0x01000000;
            hdr.second_addr =  base + 0x00F00000;
            hdr.tags_addr =    base + 0x00000100;
        } else if(!strcmp(arg, "--board")) {
            board = val;
        } else {
            return usage();
        }
    }

    if(bootimg == 0) {
        fprintf(stderr,"error: no output filename specified\n");
        return usage();
    }

    if(kernel_fn == 0) {
        fprintf(stderr,"error: no kernel image specified\n");
        return usage();
    }

    if(ramdisk_fn == 0) {
        fprintf(stderr,"error: no ramdisk image specified\n");
        return usage();
    }

    if(strlen(board) >= BOOT_NAME_SIZE) {
        fprintf(stderr,"error: board name too large\n");
        return usage();
    }

    strcpy(hdr.name, board);

#ifndef GENERIC
    hdr.kernel_addr =  KERNEL_ADDR;
    hdr.ramdisk_addr = RAMDISK_ADDR;
    if(saddr) {
        hdr.second_addr =  0x00300000;
    } else {
        hdr.second_addr =  SECONDARY_ADDR;
    }
    hdr.tags_addr   =  TAGS_ADDR;
    hdr.page_size = pagesize;
#else
    hdr.kernel_addr =  0x208000;
    hdr.ramdisk_addr = 0x1200000;
    if(saddr) {
        hdr.second_addr =  0x00300000;
    } else {
        hdr.second_addr =  0x1100000;
    }
    hdr.tags_addr   =  0x10000100;
    hdr.page_size = pagesize;
#endif

    memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);

    if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) {
        fprintf(stderr,"error: kernel commandline too large\n");
        return 1;
    }
    strcpy((char*)hdr.cmdline, cmdline);

    kernel_data = load_file(kernel_fn, &hdr.kernel_size);
    if(kernel_data == 0) {
        fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn);
        return 1;
    }

    if(!strcmp(ramdisk_fn,"NONE")) {
        ramdisk_data = 0;
        hdr.ramdisk_size = 0;
    } else {
        ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size);
        if(ramdisk_data == 0) {
            fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn);
            return 1;
        }
    }

    if(second_fn) {
        second_data = load_file(second_fn, &hdr.second_size);
        if(second_data == 0) {
            fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn);
            return 1;
        }
    }

    /* put a hash of the contents in the header so boot images can be
     * differentiated based on their first 2k.
     */
    SHA_init(&ctx);
    SHA_update(&ctx, kernel_data, hdr.kernel_size);
    SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size));
    SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size);
    SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size));
    SHA_update(&ctx, second_data, hdr.second_size);
    SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size));
    sha = SHA_final(&ctx);
    memcpy(hdr.id, sha,
           SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE);

    fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644);
    if(fd < 0) {
        fprintf(stderr,"error: could not create '%s'\n", bootimg);
        return 1;
    }

    if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;
    if(write_padding(fd, pagesize, sizeof(hdr))) goto fail;
    if(write_page_padding(fd, pagesize, sizeof(hdr))) goto fail;

    if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail;
    if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail;
    if(write_page_padding(fd, pagesize, hdr.kernel_size)) goto fail;

    if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail;
    if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;
    if(write_page_padding(fd, pagesize,  hdr.ramdisk_size)) goto fail;

    if(second_data) {
        if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail;
        if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;
        if(write_page_padding(fd, pagesize,  hdr.ramdisk_size)) goto fail;
    }

    return 0;

fail:
    unlink(bootimg);
    close(fd);
    fprintf(stderr,"error: failed writing '%s': %s\n", bootimg,
            strerror(errno));
    return 1;
}
int main(int argc, char **argv)
{
    boot_img_hdr hdr;

    char *kernel_fn = 0;
    void *kernel_data = 0;
    char *ramdisk_fn = 0;
    void *ramdisk_data = 0;
    char *second_fn = 0;
    void *second_data = 0;
    char *cmdline = "";
    char *bootimg = 0;
    char *board = "";
    char *dt_fn = 0;
    void *dt_data = 0;
    unsigned pagesize = 2048;
    int fd;
    SHA_CTX ctx;
    uint8_t* sha;
    unsigned base           = 0x10000000;
    unsigned kernel_offset  = 0x00008000;
    unsigned ramdisk_offset = 0x01000000;
    unsigned second_offset  = 0x00f00000;
    unsigned tags_offset    = 0x00000100;

    argc--;
    argv++;

    memset(&hdr, 0, sizeof(hdr));

    while(argc > 0){
        char *arg = argv[0];
        char *val = argv[1];
        if(argc < 2) {
            return usage();
        }
        argc -= 2;
        argv += 2;
        if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
            bootimg = val;
        } else if(!strcmp(arg, "--kernel")) {
            kernel_fn = val;
        } else if(!strcmp(arg, "--ramdisk")) {
            ramdisk_fn = val;
        } else if(!strcmp(arg, "--second")) {
            second_fn = val;
        } else if(!strcmp(arg, "--cmdline")) {
            cmdline = val;
        } else if(!strcmp(arg, "--base")) {
            base = strtoul(val, 0, 16);
        } else if(!strcmp(arg, "--kernel_offset")) {
            kernel_offset = strtoul(val, 0, 16);
        } else if(!strcmp(arg, "--ramdisk_offset")) {
            ramdisk_offset = strtoul(val, 0, 16);
        } else if(!strcmp(arg, "--second_offset")) {
            second_offset = strtoul(val, 0, 16);
        } else if(!strcmp(arg, "--tags_offset")) {
            tags_offset = strtoul(val, 0, 16);
        } else if(!strcmp(arg, "--board")) {
            board = val;
        } else if(!strcmp(arg,"--pagesize")) {
            pagesize = strtoul(val, 0, 10);
            if ((pagesize != 2048) && (pagesize != 4096)
                && (pagesize != 8192) && (pagesize != 16384)) {
                fprintf(stderr,"error: unsupported page size %d\n", pagesize);
                return -1;
            }
        } else if(!strcmp(arg, "--dt")) {
            dt_fn = val;
        } else {
            return usage();
        }
    }
    hdr.page_size = pagesize;

    hdr.kernel_addr =  base + kernel_offset;
    hdr.ramdisk_addr = base + ramdisk_offset;
    hdr.second_addr =  base + second_offset;
    hdr.tags_addr =    base + tags_offset;

    if(bootimg == 0) {
        fprintf(stderr,"error: no output filename specified\n");
        return usage();
    }

    if(kernel_fn == 0) {
        fprintf(stderr,"error: no kernel image specified\n");
        return usage();
    }

    if(ramdisk_fn == 0) {
        fprintf(stderr,"error: no ramdisk image specified\n");
        return usage();
    }

    if(strlen(board) >= BOOT_NAME_SIZE) {
        fprintf(stderr,"error: board name too large\n");
        return usage();
    }

    strcpy(hdr.name, board);

    memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);

    if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) {
        fprintf(stderr,"error: kernel commandline too large\n");
        return 1;
    }
    strcpy((char*)hdr.cmdline, cmdline);

    kernel_data = load_file(kernel_fn, &hdr.kernel_size);
    if(kernel_data == 0) {
        fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn);
        return 1;
    }

    if(!strcmp(ramdisk_fn,"NONE")) {
        ramdisk_data = 0;
        hdr.ramdisk_size = 0;
    } else {
        ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size);
        if(ramdisk_data == 0) {
            fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn);
            return 1;
        }
    }

    if(second_fn) {
        second_data = load_file(second_fn, &hdr.second_size);
        if(second_data == 0) {
            fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn);
            return 1;
        }
    }

    if(dt_fn) {
        dt_data = load_file(dt_fn, &hdr.dt_size);
        if (dt_data == 0) {
            fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn);
            return 1;
        }
    }

    /* put a hash of the contents in the header so boot images can be
     * differentiated based on their first 2k.
     */
    SHA_init(&ctx);
    SHA_update(&ctx, kernel_data, hdr.kernel_size);
    SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size));
    SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size);
    SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size));
    SHA_update(&ctx, second_data, hdr.second_size);
    SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size));
    if(dt_data) {
        SHA_update(&ctx, dt_data, hdr.dt_size);
        SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size));
    }
    sha = SHA_final(&ctx);
    memcpy(hdr.id, sha,
           SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE);

    fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644);
    if(fd < 0) {
        fprintf(stderr,"error: could not create '%s'\n", bootimg);
        return 1;
    }

    if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;
    if(write_padding(fd, pagesize, sizeof(hdr))) goto fail;

    if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail;
    if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail;

    if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail;
    if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;

    if(second_data) {
        if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail;
        if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;
    }

    if(dt_data) {
        if(write(fd, dt_data, hdr.dt_size) != hdr.dt_size) goto fail;
        if(write_padding(fd, pagesize, hdr.dt_size)) goto fail;
    }
    return 0;

fail:
    unlink(bootimg);
    close(fd);
    fprintf(stderr,"error: failed writing '%s': %s\n", bootimg,
            strerror(errno));
    return 1;
}
Beispiel #16
0
static bool do_join()
{
  int i,bytes_to_skip,bytes_to_xfer;
  proc_info output_proc;
  char outfilename[FILENAME_SIZE];
  wlong total=0;
  unsigned char header[CANONICAL_HEADER_SIZE];
  FILE *output;
  wave_info *joined_info;
  bool success;
  progress_info proginfo;

  success = FALSE;

  create_output_filename("","",outfilename);

  for (i=0;i<numfiles;i++)
    total += files[i]->data_size;

  if (all_files_cd_quality && (total % CD_BLOCK_SIZE) != 0) {
    pad_bytes = CD_BLOCK_SIZE - (total % CD_BLOCK_SIZE);
    if (JOIN_NOPAD != pad_type)
      total += pad_bytes;
  }

  if (NULL == (joined_info = new_wave_info(NULL))) {
    st_error("could not allocate memory for joined file information");
  }

  joined_info->chunk_size = total + CANONICAL_HEADER_SIZE - 8;
  joined_info->channels = files[0]->channels;
  joined_info->samples_per_sec = files[0]->samples_per_sec;
  joined_info->avg_bytes_per_sec = files[0]->avg_bytes_per_sec;
  joined_info->rate = files[0]->rate;
  joined_info->block_align = files[0]->block_align;
  joined_info->bits_per_sample = files[0]->bits_per_sample;
  joined_info->data_size = total;
  joined_info->wave_format = files[0]->wave_format;
  joined_info->problems = (files[0]->problems & PROBLEM_NOT_CD_QUALITY);

  if (PROB_ODD_SIZED_DATA(joined_info))
    joined_info->chunk_size++;

  joined_info->total_size = joined_info->chunk_size + 8;
  joined_info->length = joined_info->data_size / joined_info->rate;
  joined_info->exact_length = (double)joined_info->data_size / (double)joined_info->rate;

  length_to_str(joined_info);

  proginfo.initialized = FALSE;
  proginfo.prefix = "Joining";
  proginfo.clause = "-->";
  proginfo.filename1 = files[0]->filename;
  proginfo.filedesc1 = files[0]->m_ss;
  proginfo.filename2 = outfilename;
  proginfo.filedesc2 = joined_info->m_ss;
  proginfo.bytes_total = files[0]->total_size;

  prog_update(&proginfo);

  if (NULL == (output = open_output_stream(outfilename,&output_proc))) {
    st_error("could not open output file");
  }

  make_canonical_header(header,joined_info);

  if (write_n_bytes(output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) {
    prog_error(&proginfo);
    st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE);
    goto cleanup;
  }

  if (all_files_cd_quality && (JOIN_PREPAD == pad_type) && pad_bytes) {
    if (pad_bytes != write_padding(output,pad_bytes,&proginfo)) {
      prog_error(&proginfo);
      st_warning("error while pre-padding with %d zero-bytes",pad_bytes);
      goto cleanup;
    }
  }

  for (i=0;i<numfiles;i++) {
    proginfo.bytes_total = files[i]->total_size;
    proginfo.filename1 = files[i]->filename;
    proginfo.filedesc1 = files[i]->m_ss;
    prog_update(&proginfo);

    if (!open_input_stream(files[i])) {
      prog_error(&proginfo);
      st_warning("could not reopen input file");
      goto cleanup;
    }

    bytes_to_skip = files[i]->header_size;

    while (bytes_to_skip > 0) {
      bytes_to_xfer = min(bytes_to_skip,CANONICAL_HEADER_SIZE);
      if (read_n_bytes(files[i]->input,header,bytes_to_xfer,NULL) != bytes_to_xfer) {
        prog_error(&proginfo);
        st_warning("error while reading %d bytes of data",bytes_to_xfer);
        goto cleanup;
      }
      bytes_to_skip -= bytes_to_xfer;
    }

    if (transfer_n_bytes(files[i]->input,output,files[i]->data_size,&proginfo) != files[i]->data_size) {
      prog_error(&proginfo);
      st_warning("error while transferring %lu bytes of data",files[i]->data_size);
      goto cleanup;
    }

    prog_success(&proginfo);

    close_input_stream(files[i]);
  }

  if (all_files_cd_quality && JOIN_POSTPAD == pad_type && pad_bytes) {
    if (pad_bytes != write_padding(output,pad_bytes,NULL)) {
      prog_error(&proginfo);
      st_warning("error while post-padding with %d zero-bytes",pad_bytes);
      goto cleanup;
    }
  }

  if ((JOIN_NOPAD == pad_type) && PROB_ODD_SIZED_DATA(joined_info) && (1 != write_padding(output,1,NULL))) {
    prog_error(&proginfo);
    st_warning("error while NULL-padding odd-sized data chunk");
    goto cleanup;
  }

  if (all_files_cd_quality) {
    if (JOIN_NOPAD != pad_type) {
      if (pad_bytes)
        st_info("%s-padded output file with %d zero-bytes.\n",((JOIN_PREPAD == pad_type)?"Pre":"Post"),pad_bytes);
      else
        st_info("No padding needed.\n");
    }
    else {
      st_info("Output file was not padded, ");
      if (pad_bytes)
        st_info("though it needs %d bytes of padding.\n",pad_bytes);
      else
        st_info("nor was it needed.\n");
    }
  }

  success = TRUE;

cleanup:
  if ((CLOSE_CHILD_ERROR_OUTPUT == close_output(output,output_proc)) || !success) {
    success = FALSE;
    remove_file(outfilename);
    st_error("failed to join files");
  }

  return success;
}
Beispiel #17
0
int main(int argc, char *argv[])
{
   /* Any variable that begins with 't' means topocentric */
   /* Any variable that begins with 'b' means barycentric */
   FILE **outfiles = NULL;
   float **outdata;
   double dtmp, *dms, avgdm = 0.0, dsdt = 0, maxdm;
   double *dispdt, tlotoa = 0.0, blotoa = 0.0, BW_ddelay = 0.0;
   double max = -9.9E30, min = 9.9E30, var = 0.0, avg = 0.0;
   double *btoa = NULL, *ttoa = NULL, avgvoverc = 0.0;
   char obs[3], ephem[10], rastring[50], decstring[50];
   long totnumtowrite, totwrote = 0, padwrote = 0, datawrote = 0;
   int *idispdt, **offsets;
   int ii, jj, numadded = 0, numremoved = 0, padding = 0, good_inputs = 1;
   int numbarypts = 0, numread = 0, numtowrite = 0;
   int padtowrite = 0, statnum = 0;
   int numdiffbins = 0, *diffbins = NULL, *diffbinptr = NULL, good_padvals = 0;
   double local_lodm;
   char *datafilenm, *outpath, *outfilenm, *hostname;
   struct spectra_info s;
   infodata idata;
   mask obsmask;

   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
   MPI_Comm_rank(MPI_COMM_WORLD, &myid);
#ifdef _OPENMP
   omp_set_num_threads(1); // Explicitly turn off OpenMP
#endif
   set_using_MPI();
   {
      FILE *hostfile;
      char tmpname[100];
      int retval;

      hostfile = chkfopen("/etc/hostname", "r");
      retval = fscanf(hostfile, "%s\n", tmpname);
      if (retval==0) {
          printf("Warning:  error reading /etc/hostname on proc %d\n", myid);
      }
      hostname = (char *) calloc(strlen(tmpname) + 1, 1);
      memcpy(hostname, tmpname, strlen(tmpname));
      fclose(hostfile);
   }

   /* Call usage() if we have no command line arguments */

   if (argc == 1) {
      if (myid == 0) {
         Program = argv[0];
         usage();
      }
      MPI_Finalize();
      exit(1);
   }

   make_maskbase_struct();
   make_spectra_info_struct();

   /* Parse the command line using the excellent program Clig */

   cmd = parseCmdline(argc, argv);
   spectra_info_set_defaults(&s);
   // If we are zeroDMing, make sure that clipping is off.
   if (cmd->zerodmP) cmd->noclipP = 1;
   s.clip_sigma = cmd->clip;
   if (cmd->noclipP) {
       cmd->clip = 0.0;
       s.clip_sigma = 0.0;
   }
   if (cmd->ifsP) {
       // 0 = default or summed, 1-4 are possible also
       s.use_poln = cmd->ifs + 1;
   }
   if (!cmd->numoutP)
      cmd->numout = LONG_MAX;

#ifdef DEBUG
   showOptionValues();
#endif

   if (myid == 0) {             /* Master node only */
      printf("\n\n");
      printf("      Parallel Pulsar Subband De-dispersion Routine\n");
      printf("                 by Scott M. Ransom\n\n");

      s.filenames = cmd->argv;
      s.num_files = cmd->argc;
      s.clip_sigma = cmd->clip;
      // -1 causes the data to determine if we use weights, scales, & 
      // offsets for PSRFITS or flip the band for any data type where
      // we can figure that out with the data
      s.apply_flipband = (cmd->invertP) ? 1 : -1;
      s.apply_weight = (cmd->noweightsP) ? 0 : -1;
      s.apply_scale  = (cmd->noscalesP) ? 0 : -1;
      s.apply_offset = (cmd->nooffsetsP) ? 0 : -1;
      s.remove_zerodm = (cmd->zerodmP) ? 1 : 0;

      if (RAWDATA) {
          if (cmd->filterbankP) s.datatype = SIGPROCFB;
          else if (cmd->psrfitsP) s.datatype = PSRFITS;
          else if (cmd->pkmbP) s.datatype = SCAMP;
          else if (cmd->bcpmP) s.datatype = BPP;
          else if (cmd->wappP) s.datatype = WAPP;
          else if (cmd->spigotP) s.datatype = SPIGOT;
      } else {  // Attempt to auto-identify the data
          identify_psrdatatype(&s, 1);
          if (s.datatype==SIGPROCFB) cmd->filterbankP = 1;
          else if (s.datatype==PSRFITS) cmd->psrfitsP = 1;
          else if (s.datatype==SCAMP) cmd->pkmbP = 1;
          else if (s.datatype==BPP) cmd->bcpmP = 1;
          else if (s.datatype==WAPP) cmd->wappP = 1;
          else if (s.datatype==SPIGOT) cmd->spigotP = 1;
          else if (s.datatype==SUBBAND) insubs = 1;
          else {
              printf("\nError:  Unable to identify input data files.  Please specify type.\n\n");
              good_inputs = 0;
          }
      }
      // So far we can only handle PSRFITS, filterbank, and subbands
      if (s.datatype!=PSRFITS && 
          s.datatype!=SIGPROCFB && 
          s.datatype!=SUBBAND) good_inputs = 0;

      // For subbanded data
      if (!RAWDATA) s.files = (FILE **)malloc(sizeof(FILE *) * s.num_files);

      if (good_inputs && (RAWDATA || insubs)) {
          char description[40];
          psrdatatype_description(description, s.datatype);
          if (s.num_files > 1)
              printf("Reading %s data from %d files:\n", description, s.num_files);
          else
              printf("Reading %s data from 1 file:\n", description);
          for (ii = 0; ii < s.num_files; ii++) {
              printf("  '%s'\n", cmd->argv[ii]);
              if (insubs) s.files[ii] = chkfopen(s.filenames[ii], "rb");
          }
          printf("\n");
          if (RAWDATA) {
              read_rawdata_files(&s);
              print_spectra_info_summary(&s);
              spectra_info_to_inf(&s, &idata);
          } else { // insubs
              char *root, *suffix;
              cmd->nsub = s.num_files;
              s.N = chkfilelen(s.files[0], sizeof(short));
              s.start_subint = gen_ivect(1);
              s.num_subint = gen_ivect(1);
              s.start_MJD = (long double *)malloc(sizeof(long double));
              s.start_spec = (long long *)malloc(sizeof(long long));
              s.num_spec = (long long *)malloc(sizeof(long long));
              s.num_pad = (long long *)malloc(sizeof(long long));
              s.start_spec[0] = 0L;
              s.start_subint[0] = 0;
              s.num_spec[0] = s.N;
              s.num_subint[0] = s.N / SUBSBLOCKLEN;
              s.num_pad[0] = 0L;
              s.padvals = gen_fvect(s.num_files);
              for (ii = 0 ; ii < ii ; ii++)
                  s.padvals[ii] = 0.0;
              if (split_root_suffix(s.filenames[0], &root, &suffix) == 0) {
                  printf("\nError:  The input filename (%s) must have a suffix!\n\n", s.filenames[0]);
                  exit(1);
              }
              if (strncmp(suffix, "sub", 3) == 0) {
                  char *tmpname;
                  tmpname = calloc(strlen(root) + 10, 1);
                  sprintf(tmpname, "%s.sub", root);
                  readinf(&idata, tmpname);
                  free(tmpname);
                  strncpy(s.telescope, idata.telescope, 40);
                  strncpy(s.backend, idata.instrument, 40);
                  strncpy(s.observer, idata.observer, 40);
                  strncpy(s.source, idata.object, 40);
                  s.ra2000 = hms2rad(idata.ra_h, idata.ra_m,
                                     idata.ra_s) * RADTODEG;
                  s.dec2000 = dms2rad(idata.dec_d, idata.dec_m,
                                      idata.dec_s) * RADTODEG;
                  ra_dec_to_string(s.ra_str,
                                   idata.ra_h, idata.ra_m, idata.ra_s);
                  ra_dec_to_string(s.dec_str,
                                   idata.dec_d, idata.dec_m, idata.dec_s);
                  s.num_channels = idata.num_chan;
                  s.start_MJD[0] = idata.mjd_i + idata.mjd_f;
                  s.dt = idata.dt;
                  s.T = s.N * s.dt;
                  s.lo_freq = idata.freq;
                  s.df = idata.chan_wid;
                  s.hi_freq = s.lo_freq + (s.num_channels - 1.0) * s.df;
                  s.BW = s.num_channels * s.df;
                  s.fctr = s.lo_freq - 0.5 * s.df + 0.5 * s.BW;
                  s.beam_FWHM = idata.fov / 3600.0;
                  s.spectra_per_subint = SUBSBLOCKLEN;
                  print_spectra_info_summary(&s);
              } else {
                  printf("\nThe input files (%s) must be subbands!  (i.e. *.sub##)\n\n",
                         cmd->argv[0]);
                  MPI_Finalize();
                  exit(1);
              }
              free(root);
              free(suffix);
          }
      }
   }

   //  If we don't have good input data, exit
   MPI_Bcast(&good_inputs, 1, MPI_INT, 0, MPI_COMM_WORLD);
   if (!good_inputs) {
       MPI_Finalize();
       exit(1);
   }
   
   MPI_Bcast(&insubs, 1, MPI_INT, 0, MPI_COMM_WORLD);
   if (insubs)
       cmd->nsub = cmd->argc;

   /* Determine the output file names and open them */

   local_numdms = cmd->numdms / (numprocs - 1);
   dms = gen_dvect(local_numdms);
   if (cmd->numdms % (numprocs - 1)) {
       if (myid == 0)
           printf
               ("\nThe number of DMs must be divisible by (the number of processors - 1).\n\n");
       MPI_Finalize();
       exit(1);
   }
   local_lodm = cmd->lodm + (myid - 1) * local_numdms * cmd->dmstep;
   
   split_path_file(cmd->outfile, &outpath, &outfilenm);
   datafilenm = (char *) calloc(strlen(outfilenm) + 20, 1);
   if (myid > 0) {
       if (chdir(outpath) == -1) {
           printf("\nProcess %d on %s cannot chdir() to '%s'.  Exiting.\n\n", 
                  myid, hostname, outpath);
           MPI_Finalize();
           exit(1);
       }
       outfiles = (FILE **) malloc(local_numdms * sizeof(FILE *));
       for (ii = 0; ii < local_numdms; ii++) {
           dms[ii] = local_lodm + ii * cmd->dmstep;
           avgdm += dms[ii];
           sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]);
           outfiles[ii] = chkfopen(datafilenm, "wb");
       }
       avgdm /= local_numdms;
   }
   
   // Broadcast the raw data information

   broadcast_spectra_info(&s, myid);
   if (myid > 0) {
       spectra_info_to_inf(&s, &idata);
       if (s.datatype==SIGPROCFB) cmd->filterbankP = 1;
       else if (s.datatype==PSRFITS) cmd->psrfitsP = 1;
       else if (s.datatype==SCAMP) cmd->pkmbP = 1;
       else if (s.datatype==BPP) cmd->bcpmP = 1;
       else if (s.datatype==WAPP) cmd->wappP = 1;
       else if (s.datatype==SPIGOT) cmd->spigotP = 1;
       else if (s.datatype==SUBBAND) insubs = 1;
   }
   s.filenames = cmd->argv;

   /* Read an input mask if wanted */
   
   if (myid > 0) {
       int numpad = s.num_channels;
       if (insubs)
           numpad = s.num_files;
       s.padvals = gen_fvect(numpad);
       for (ii = 0 ; ii < numpad ; ii++)
           s.padvals[ii] = 0.0;
   }
   if (cmd->maskfileP) {
       if (myid == 0) {
           read_mask(cmd->maskfile, &obsmask);
           printf("Read mask information from '%s'\n\n", cmd->maskfile);
           good_padvals = determine_padvals(cmd->maskfile, &obsmask, s.padvals);
       }
       broadcast_mask(&obsmask, myid);
       MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD);
       MPI_Bcast(s.padvals, obsmask.numchan, MPI_FLOAT, 0, MPI_COMM_WORLD);
   } else {
       obsmask.numchan = obsmask.numint = 0;
       MPI_Bcast(&good_padvals, 1, MPI_INT, 0, MPI_COMM_WORLD);
   }

   // The number of topo to bary time points to generate with TEMPO
   numbarypts = (int) (s.T * 1.1 / TDT + 5.5) + 1;

   // Identify the TEMPO observatory code
   {
       char *outscope = (char *) calloc(40, sizeof(char));
       telescope_to_tempocode(idata.telescope, outscope, obs);
       free(outscope);
   }

   // Broadcast or calculate a few extra important values
   if (insubs) avgdm = idata.dm;
   idata.dm = avgdm;
   dsdt = cmd->downsamp * idata.dt;
   maxdm = cmd->lodm + cmd->numdms * cmd->dmstep;
   BW_ddelay = delay_from_dm(maxdm, idata.freq) - 
       delay_from_dm(maxdm, idata.freq + (idata.num_chan-1) * idata.chan_wid);
   blocksperread = ((int) (BW_ddelay / idata.dt) / s.spectra_per_subint + 1);
   worklen = s.spectra_per_subint * blocksperread;
   
   if (cmd->nsub > s.num_channels) {
      printf
          ("Warning:  The number of requested subbands (%d) is larger than the number of channels (%d).\n",
           cmd->nsub, s.num_channels);
      printf("          Re-setting the number of subbands to %d.\n\n", s.num_channels);
      cmd->nsub = s.num_channels;
   }

   if (s.spectra_per_subint % cmd->downsamp) {
       if (myid == 0) {
           printf
               ("\nError:  The downsample factor (%d) must be a factor of the\n",
                cmd->downsamp);
           printf("        blocklength (%d).  Exiting.\n\n", s.spectra_per_subint);
       }
       MPI_Finalize();
       exit(1);
   }

   tlotoa = idata.mjd_i + idata.mjd_f;  /* Topocentric epoch */

   if (cmd->numoutP)
      totnumtowrite = cmd->numout;
   else
      totnumtowrite = (long) idata.N / cmd->downsamp;

   if (cmd->nobaryP) {          /* Main loop if we are not barycentering... */

      /* Dispersion delays (in bins).  The high freq gets no delay   */
      /* All other delays are positive fractions of bin length (dt)  */

      dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm,
                                     idata.freq, idata.chan_wid, 0.0);
      idispdt = gen_ivect(s.num_channels);
      for (ii = 0; ii < s.num_channels; ii++)
          idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt);
      vect_free(dispdt);

      /* The subband dispersion delays (see note above) */

      offsets = gen_imatrix(local_numdms, cmd->nsub);
      for (ii = 0; ii < local_numdms; ii++) {
         double *subdispdt;

         subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii],
                                    idata.freq, idata.chan_wid, 0.0);
         dtmp = subdispdt[cmd->nsub - 1];
         for (jj = 0; jj < cmd->nsub; jj++)
            offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt);
         vect_free(subdispdt);
      }

      /* Allocate our data array and start getting data */

      if (myid == 0) {
         printf("De-dispersing using %d subbands.\n", cmd->nsub);
         if (cmd->downsamp > 1)
            printf("Downsampling by a factor of %d (new dt = %.10g)\n",
                   cmd->downsamp, dsdt);
         printf("\n");
      }
      
      /* Print the nodes and the DMs they are handling */
      print_dms(hostname, myid, numprocs, local_numdms, dms);

      outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp);
      numread = get_data(outdata, blocksperread, &s,
                         &obsmask, idispdt, offsets, &padding);

      while (numread == worklen) {

         numread /= cmd->downsamp;
         if (myid == 0)
            print_percent_complete(totwrote, totnumtowrite);

         /* Write the latest chunk of data, but don't   */
         /* write more than cmd->numout points.         */

         numtowrite = numread;
         if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout)
            numtowrite = cmd->numout - totwrote;
         if (myid > 0) {
            write_data(outfiles, local_numdms, outdata, 0, numtowrite);
            /* Update the statistics */
            if (!padding) {
               for (ii = 0; ii < numtowrite; ii++)
                  update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var);
               statnum += numtowrite;
            }
         }
         totwrote += numtowrite;

         /* Stop if we have written out all the data we need to */

         if (cmd->numoutP && (totwrote == cmd->numout))
            break;

         numread = get_data(outdata, blocksperread, &s,
                            &obsmask, idispdt, offsets, &padding);
      }
      datawrote = totwrote;

   } else {                     /* Main loop if we are barycentering... */

      /* What ephemeris will we use?  (Default is DE405) */
      strcpy(ephem, "DE405");

      /* Define the RA and DEC of the observation */

      ra_dec_to_string(rastring, idata.ra_h, idata.ra_m, idata.ra_s);
      ra_dec_to_string(decstring, idata.dec_d, idata.dec_m, idata.dec_s);

      /* Allocate some arrays */

      btoa = gen_dvect(numbarypts);
      ttoa = gen_dvect(numbarypts);
      for (ii = 0; ii < numbarypts; ii++)
         ttoa[ii] = tlotoa + TDT * ii / SECPERDAY;

      /* Call TEMPO for the barycentering */

      if (myid == 0) {
         double maxvoverc = -1.0, minvoverc = 1.0, *voverc = NULL;

         printf("\nGenerating barycentric corrections...\n");
         voverc = gen_dvect(numbarypts);
         barycenter(ttoa, btoa, voverc, numbarypts, rastring, decstring, obs, ephem);
         for (ii = 0; ii < numbarypts; ii++) {
            if (voverc[ii] > maxvoverc)
               maxvoverc = voverc[ii];
            if (voverc[ii] < minvoverc)
               minvoverc = voverc[ii];
            avgvoverc += voverc[ii];
         }
         avgvoverc /= numbarypts;
         vect_free(voverc);

         printf("   Average topocentric velocity (c) = %.7g\n", avgvoverc);
         printf("   Maximum topocentric velocity (c) = %.7g\n", maxvoverc);
         printf("   Minimum topocentric velocity (c) = %.7g\n\n", minvoverc);
         printf("De-dispersing using %d subbands.\n", cmd->nsub);
         if (cmd->downsamp > 1) {
             printf("     Downsample = %d\n", cmd->downsamp);
             printf("  New sample dt = %.10g\n", dsdt);
         }
         printf("\n");
      }

      /* Print the nodes and the DMs they are handling */
      print_dms(hostname, myid, numprocs, local_numdms, dms);

      MPI_Bcast(btoa, numbarypts, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      MPI_Bcast(&avgvoverc, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
      blotoa = btoa[0];

      /* Dispersion delays (in bins).  The high freq gets no delay   */
      /* All other delays are positive fractions of bin length (dt)  */

      dispdt = subband_search_delays(s.num_channels, cmd->nsub, avgdm,
                                     idata.freq, idata.chan_wid, avgvoverc);
      idispdt = gen_ivect(s.num_channels);
      for (ii = 0; ii < s.num_channels; ii++)
          idispdt[ii] = NEAREST_LONG(dispdt[ii] / idata.dt);
      vect_free(dispdt);

      /* The subband dispersion delays (see note above) */

      offsets = gen_imatrix(local_numdms, cmd->nsub);
      for (ii = 0; ii < local_numdms; ii++) {
         double *subdispdt;

         subdispdt = subband_delays(s.num_channels, cmd->nsub, dms[ii],
                                    idata.freq, idata.chan_wid, avgvoverc);
         dtmp = subdispdt[cmd->nsub - 1];
         for (jj = 0; jj < cmd->nsub; jj++)
            offsets[ii][jj] = NEAREST_LONG((subdispdt[jj] - dtmp) / dsdt);
         vect_free(subdispdt);
      }

      /* Convert the bary TOAs to differences from the topo TOAs in */
      /* units of bin length (dt) rounded to the nearest integer.   */

      dtmp = (btoa[0] - ttoa[0]);
      for (ii = 0; ii < numbarypts; ii++)
         btoa[ii] = ((btoa[ii] - ttoa[ii]) - dtmp) * SECPERDAY / dsdt;

      /* Find the points where we need to add or remove bins */
      {
         int oldbin = 0, currentbin;
         double lobin, hibin, calcpt;

         numdiffbins = abs(NEAREST_LONG(btoa[numbarypts - 1])) + 1;
         diffbins = gen_ivect(numdiffbins);
         diffbinptr = diffbins;
         for (ii = 1; ii < numbarypts; ii++) {
            currentbin = NEAREST_LONG(btoa[ii]);
            if (currentbin != oldbin) {
               if (currentbin > 0) {
                  calcpt = oldbin + 0.5;
                  lobin = (ii - 1) * TDT / dsdt;
                  hibin = ii * TDT / dsdt;
               } else {
                  calcpt = oldbin - 0.5;
                  lobin = -((ii - 1) * TDT / dsdt);
                  hibin = -(ii * TDT / dsdt);
               }
               while (fabs(calcpt) < fabs(btoa[ii])) {
                  /* Negative bin number means remove that bin */
                  /* Positive bin number means add a bin there */
                  *diffbinptr =
                      NEAREST_LONG(LININTERP
                                  (calcpt, btoa[ii - 1], btoa[ii], lobin, hibin));
                  diffbinptr++;
                  calcpt = (currentbin > 0) ? calcpt + 1.0 : calcpt - 1.0;
               }
               oldbin = currentbin;
            }
         }
         *diffbinptr = cmd->numout; /* Used as a marker */
      }
      diffbinptr = diffbins;

      /* Now perform the barycentering */

      outdata = gen_fmatrix(local_numdms, worklen / cmd->downsamp);
      numread = get_data(outdata, blocksperread, &s, 
                         &obsmask, idispdt, offsets, &padding);

      while (numread == worklen) {      /* Loop to read and write the data */
         int numwritten = 0;
         double block_avg, block_var;

         numread /= cmd->downsamp;
         /* Determine the approximate local average */
         avg_var(outdata[0], numread, &block_avg, &block_var);
         if (myid == 0)
            print_percent_complete(totwrote, totnumtowrite);

         /* Simply write the data if we don't have to add or */
         /* remove any bins from this batch.                 */
         /* OR write the amount of data up to cmd->numout or */
         /* the next bin that will be added or removed.      */

         numtowrite = abs(*diffbinptr) - datawrote;
         if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout)
            numtowrite = cmd->numout - totwrote;
         if (numtowrite > numread)
            numtowrite = numread;
         if (myid > 0) {
            write_data(outfiles, local_numdms, outdata, 0, numtowrite);
            /* Update the statistics */
            if (!padding) {
               for (ii = 0; ii < numtowrite; ii++)
                  update_stats(statnum + ii, outdata[0][ii], &min, &max, &avg, &var);
               statnum += numtowrite;
            }
         }
         datawrote += numtowrite;
         totwrote += numtowrite;
         numwritten += numtowrite;

         if ((datawrote == abs(*diffbinptr)) && 
             (numwritten != numread) && 
             (totwrote < cmd->numout)) {  /* Add/remove a bin */
            int skip, nextdiffbin;

            skip = numtowrite;

            /* Write the rest of the data after adding/removing a bin  */
            do {

               if (*diffbinptr > 0) {
                  /* Add a bin */
                  if (myid > 0)
                     write_padding(outfiles, local_numdms, block_avg, 1);
                  numadded++;
                  totwrote++;
               } else {
                  /* Remove a bin */
                  numremoved++;
                  datawrote++;
                  numwritten++;
                  skip++;
               }
               diffbinptr++;

               /* Write the part after the diffbin */

               numtowrite = numread - numwritten;
               if (cmd->numoutP && (totwrote + numtowrite) > cmd->numout)
                  numtowrite = cmd->numout - totwrote;
               nextdiffbin = abs(*diffbinptr) - datawrote;
               if (numtowrite > nextdiffbin)
                  numtowrite = nextdiffbin;
               if (myid > 0) {
                  write_data(outfiles, local_numdms, outdata, skip, numtowrite);
                  /* Update the statistics and counters */
                  if (!padding) {
                     for (ii = 0; ii < numtowrite; ii++)
                        update_stats(statnum + ii,
                                     outdata[0][skip + ii], &min, &max, &avg, &var);
                     statnum += numtowrite;
                  }
               }
               numwritten += numtowrite;
               datawrote += numtowrite;
               totwrote += numtowrite;
               skip += numtowrite;

               /* Stop if we have written out all the data we need to */

               if (cmd->numoutP && (totwrote == cmd->numout))
                  break;
            } while (numwritten < numread);
         }
         /* Stop if we have written out all the data we need to */

         if (cmd->numoutP && (totwrote == cmd->numout))
            break;

         numread = get_data(outdata, blocksperread, &s,
                            &obsmask, idispdt, offsets, &padding);
      }
   }

   if (myid > 0) {

      /* Calculate the amount of padding we need  */

      if (cmd->numoutP && (cmd->numout > totwrote))
         padwrote = padtowrite = cmd->numout - totwrote;

      /* Write the new info file for the output data */

      idata.dt = dsdt;
      update_infodata(&idata, totwrote, padtowrite, diffbins,
                      numdiffbins, cmd->downsamp);
      for (ii = 0; ii < local_numdms; ii++) {
         idata.dm = dms[ii];
         if (!cmd->nobaryP) {
            double baryepoch, barydispdt, baryhifreq;

            baryhifreq = idata.freq + (s.num_channels - 1) * idata.chan_wid;
            barydispdt = delay_from_dm(dms[ii], doppler(baryhifreq, avgvoverc));
            baryepoch = blotoa - (barydispdt / SECPERDAY);
            idata.bary = 1;
            idata.mjd_i = (int) floor(baryepoch);
            idata.mjd_f = baryepoch - idata.mjd_i;
         }
         sprintf(idata.name, "%s_DM%.2f", outfilenm, dms[ii]);
         writeinf(&idata);
      }

      /* Set the padded points equal to the average data point */

      if (idata.numonoff >= 1) {
         int index, startpad, endpad;

         for (ii = 0; ii < local_numdms; ii++) {
            fclose(outfiles[ii]);
            sprintf(datafilenm, "%s_DM%.2f.dat", outfilenm, dms[ii]);
            outfiles[ii] = chkfopen(datafilenm, "rb+");
         }
         for (ii = 0; ii < idata.numonoff; ii++) {
            index = 2 * ii;
            startpad = idata.onoff[index + 1];
            if (ii == idata.numonoff - 1)
               endpad = idata.N - 1;
            else
               endpad = idata.onoff[index + 2];
            for (jj = 0; jj < local_numdms; jj++)
               chkfseek(outfiles[jj], (startpad + 1) * sizeof(float), SEEK_SET);
            padtowrite = endpad - startpad;
            write_padding(outfiles, local_numdms, avg, padtowrite);
         }
      }
   }

   /* Print simple stats and results */

   var /= (datawrote - 1);
   if (myid == 0)
      print_percent_complete(1, 1);
   if (myid == 1) {
      printf("\n\nDone.\n\nSimple statistics of the output data:\n");
      printf("             Data points written:  %ld\n", totwrote);
      if (padwrote)
         printf("          Padding points written:  %ld\n", padwrote);
      if (!cmd->nobaryP) {
         if (numadded)
            printf("    Bins added for barycentering:  %d\n", numadded);
         if (numremoved)
            printf("  Bins removed for barycentering:  %d\n", numremoved);
      }
      printf("           Maximum value of data:  %.2f\n", max);
      printf("           Minimum value of data:  %.2f\n", min);
      printf("              Data average value:  %.2f\n", avg);
      printf("         Data standard deviation:  %.2f\n", sqrt(var));
      printf("\n");
   }

   /* Close the files and cleanup */

   if (cmd->maskfileP)
      free_mask(obsmask);
   if (myid > 0) {
      for (ii = 0; ii < local_numdms; ii++)
         fclose(outfiles[ii]);
      free(outfiles);
   }
   vect_free(outdata[0]);
   vect_free(outdata);
   vect_free(dms);
   free(hostname);
   vect_free(idispdt);
   vect_free(offsets[0]);
   vect_free(offsets);
   free(datafilenm);
   free(outfilenm);
   free(outpath);
   if (!cmd->nobaryP) {
      vect_free(btoa);
      vect_free(ttoa);
      vect_free(diffbins);
   }
   MPI_Finalize();
   return (0);
}
int main(int argc, char **argv)
{
    boot_img_hdr hdr;

    char *kernel_fn = NULL;
    void *kernel_data = NULL;
    char *ramdisk_fn = NULL;
    void *ramdisk_data = NULL;
    char *second_fn = NULL;
    void *second_data = NULL;
    char *cmdline = "";
    char *bootimg = NULL;
    char *board = "";
    char *dt_fn = NULL;
    void *dt_data = NULL;
    uint32_t pagesize = 2048;
    int fd;
    SHA_CTX ctx;
    const uint8_t* sha;
    uint32_t base           = 0x10000000U;
    uint32_t kernel_offset  = 0xFE208100;
    uint32_t ramdisk_offset = 0x00200100;
    uint32_t second_offset  = 0xFF100100;
    uint32_t tags_offset    = 0x00000100U;
    size_t cmdlen;

    argc--;
    argv++;

    memset(&hdr, 0, sizeof(hdr));

    bool get_id = false;
    while(argc > 0){
        char *arg = argv[0];
        if (!strcmp(arg, "--id")) {
            get_id = true;
            argc -= 1;
            argv += 1;
        } else if(argc >= 2) {
            char *val = argv[1];
            argc -= 2;
            argv += 2;
            if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
                bootimg = val;
            } else if(!strcmp(arg, "--kernel")) {
                kernel_fn = val;
            } else if(!strcmp(arg, "--ramdisk")) {
                ramdisk_fn = val;
            } else if(!strcmp(arg, "--second")) {
                second_fn = val;
            } else if(!strcmp(arg, "--cmdline")) {
                cmdline = val;
            } else if(!strcmp(arg, "--base")) {
                base = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--kernel_offset")) {
                kernel_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--ramdisk_offset")) {
                ramdisk_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--second_offset")) {
                second_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--tags_offset")) {
                tags_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--board")) {
                board = val;
            } else if(!strcmp(arg,"--pagesize")) {
                pagesize = strtoul(val, 0, 10);
                if ((pagesize != 2048) && (pagesize != 4096)
                    && (pagesize != 8192) && (pagesize != 16384)
                    && (pagesize != 32768) && (pagesize != 65536)
                    && (pagesize != 131072)) {
                    fprintf(stderr,"error: unsupported page size %d\n", pagesize);
                    return -1;
                }
            } else if(!strcmp(arg, "--dt")) {
                dt_fn = val;
            } else {
                return usage();
            }
        } else {
            return usage();
        }
    }
    hdr.page_size = pagesize;

    hdr.kernel_addr =  base + kernel_offset;
    hdr.ramdisk_addr = base + ramdisk_offset;
    hdr.second_addr =  base + second_offset;
    hdr.tags_addr =    base + tags_offset;

    if(bootimg == 0) {
        fprintf(stderr,"error: no output filename specified\n");
        return usage();
    }

    if(kernel_fn == 0) {
        fprintf(stderr,"error: no kernel image specified\n");
        return usage();
    }

    if(ramdisk_fn == 0) {
        fprintf(stderr,"error: no ramdisk image specified\n");
        return usage();
    }

    if(strlen(board) >= BOOT_NAME_SIZE) {
        fprintf(stderr,"error: board name too large\n");
        return usage();
    }

    strcpy((char *) hdr.name, board);

    memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);

    cmdlen = strlen(cmdline);
    if(cmdlen > (BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 2)) {
        fprintf(stderr,"error: kernel commandline too large\n");
        return 1;
    }
    /* Even if we need to use the supplemental field, ensure we
     * are still NULL-terminated */
    strncpy((char *)hdr.cmdline, cmdline, BOOT_ARGS_SIZE - 1);
    hdr.cmdline[BOOT_ARGS_SIZE - 1] = '\0';
    if (cmdlen >= (BOOT_ARGS_SIZE - 1)) {
        cmdline += (BOOT_ARGS_SIZE - 1);
        strncpy((char *)hdr.extra_cmdline, cmdline, BOOT_EXTRA_ARGS_SIZE);
    }

    kernel_data = load_file(kernel_fn, &hdr.kernel_size);
    if(kernel_data == 0) {
        fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn);
        return 1;
    }

    if(!strcmp(ramdisk_fn,"NONE")) {
        ramdisk_data = 0;
        hdr.ramdisk_size = 0;
    } else {
        ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size);
        if(ramdisk_data == 0) {
            fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn);
            return 1;
        }
    }

    if(second_fn) {
        second_data = load_file(second_fn, &hdr.second_size);
        if(second_data == 0) {
            fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn);
            return 1;
        }
    }

    if(dt_fn) {
        dt_data = load_file(dt_fn, &hdr.dt_size);
        if (dt_data == 0) {
            fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn);
            return 1;
        }
    }

    /* put a hash of the contents in the header so boot images can be
     * differentiated based on their first 2k.
     */
    SHA_init(&ctx);
    SHA_update(&ctx, kernel_data, hdr.kernel_size);
    SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size));
    SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size);
    SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size));
    SHA_update(&ctx, second_data, hdr.second_size);
    SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size));
    if(dt_data) {
        SHA_update(&ctx, dt_data, hdr.dt_size);
        SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size));
    }
    sha = SHA_final(&ctx);
    memcpy(hdr.id, sha,
           SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE);

    fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644);
    if(fd < 0) {
        fprintf(stderr,"error: could not create '%s'\n", bootimg);
        return 1;
    }

    if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;
    if(write_padding(fd, pagesize, sizeof(hdr))) goto fail;

    if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail;
    if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail;

    if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail;
    if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;

    if(second_data) {
        if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail;
        if(write_padding(fd, pagesize, hdr.second_size)) goto fail;
    }

    if(dt_data) {
        if(write(fd, dt_data, hdr.dt_size) != (ssize_t) hdr.dt_size) goto fail;
        if(write_padding(fd, pagesize, hdr.dt_size)) goto fail;
    }

    if (get_id) {
        print_id((uint8_t *) hdr.id, sizeof(hdr.id));
    }

    return 0;

fail:
    unlink(bootimg);
    close(fd);
    fprintf(stderr,"error: failed writing '%s': %s\n", bootimg,
            strerror(errno));
    return 1;
}
Beispiel #19
0
int pack_main(char *dir, char *bootimg) {
  char tmp[PATH_MAX];
  char *img_info = 0;
  char *kernel_fn;
  void *kernel_data;
  char *ramdisk_fn;
  void *ramdisk_data = 0;
  char *second_fn = 0;
  void *second_data = 0;
  FILE *flag_fn = 0;
  unsigned char *flag_data[512];
  char *board = "";
  char *dt_fn = 0;
  void *dt_data = 0;
 		int fd;
  SHA_CTX ctx;
  const uint8_t *sha;
  int _BOOTIMG_MTK = 0;


  memset(&hdr, 0, sizeof(hdr));
  char *__now_path = getcwd(NULL, NULL);
  hdr.kernel_addr = 0x10008000;
  hdr.ramdisk_addr = 0x11000000;
  hdr.second_addr = 0x10F00000;
  hdr.tags_addr = 0x10000100;
  chdir(dir);
  repack_ramdisk_main(dir);
  sprintf(tmp, "%s/%s", __now_path, bootimg);
  bootimg = tmp;
  kernel_fn = "zImage";
  ramdisk_fn = "ramdisk-new.cpio.gz";
  dt_fn = "dt.img";
  img_info = "img_info.txt";

  if (exist(kernel_fn)) {
    fprintf(stderr, "找不到:%s\n", kernel_fn);
    //exit(-1);
  }
  if (exist(ramdisk_fn)) {
    fprintf(stderr, "找不到:%s\n", ramdisk_fn);
    //exit(-1);
  }
  if (exist(dt_fn)) {
    //fprintf(stderr, "no dt.img\n", dt_fn);
    dt_fn = 0;
  }
  if (exist(img_info)) {
    fprintf(stderr, "找不到:%s\n", img_info);
    //exit(-1);
  }
  if(!exist(".mtk_flag")){
  		_BOOTIMG_MTK = 1;
  }
  read_img_info(img_info);
  if(_BOOTIMG_MTK){
    	cmdline = "";
   }
  hdr.page_size = pagesize;
  strcpy((char *)hdr.name, board);
  memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);
    if(_BOOTIMG_MTK){
 	 // MTK 需要多写入512字节
 	 char *ram_old = ramdisk_fn;
 	 char *ram_new = "ramdisk-new.cpio.gz.revised";
 	 FILE *flag_fn = fopen(".mtk_flag", "rb");
 	 fread(flag_data, 512, 1, flag_fn);
 	 FILE *ram_fn = fopen(ram_old, "rb");
 	 fseek(ram_fn, 0, SEEK_END);
 	 long ram_size = ftell(ram_fn);
 	 fseek(ram_fn, 0, SEEK_SET);
 	 unsigned char buf[ram_size];
 	 fread(buf, ram_size, 1, ram_fn);
 	 FILE *new_fn = fopen(ram_new, "wb");
 	 fwrite(flag_data, 512, 1, new_fn);
 	 fwrite(buf, ram_size, 1, new_fn);
 	 fclose(ram_fn);
 	 fclose(new_fn);
 	 fclose(flag_fn);
 	 unlink(ram_old);
 	 ramdisk_fn = ram_new;
  }
  if (strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) {
    fprintf(stderr, "error: kernel commandline too large\n");
    return 1;
  }
  strcpy((char *)hdr.cmdline, cmdline);

  kernel_data = load_file(kernel_fn, &hdr.kernel_size);
  if (!strcmp(ramdisk_fn, "NONE")) {
    ramdisk_data = 0;
    hdr.ramdisk_size = 0;
  } else {
    ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size);
  }
  if (second_fn) {
    second_data = load_file(second_fn, &hdr.second_size);
    if (second_data == 0) {
      fprintf(stderr, "error: could not load secondstage '%s'\n", second_fn);
      return 1;
    }
  }

  if (dt_fn) {
    dt_data = load_file(dt_fn, &hdr.dt_size);
    if (dt_data == 0) {
      fprintf(stderr, "error: could not load device tree image '%s'\n", dt_fn);
      return 1;
    }
  }

  /* put a hash of the contents in the header so boot images can be
     differentiated based on their first 2k. */
  SHA_init(&ctx);
  SHA_update(&ctx, kernel_data, (int)hdr.kernel_size);
  SHA_update(&ctx, &hdr.kernel_size, (int)sizeof(hdr.kernel_size));
  SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size);
  SHA_update(&ctx, &hdr.ramdisk_size, (int)sizeof(hdr.ramdisk_size));
  SHA_update(&ctx, second_data, (int)hdr.second_size);
  SHA_update(&ctx, &hdr.second_size, (int)sizeof(hdr.second_size));
  if (dt_data) {
    SHA_update(&ctx, dt_data, hdr.dt_size);
    SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size));
  }
  sha = SHA_final(&ctx);
  memcpy(hdr.id, sha,
         SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE);

  fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0777);
  if (fd < 0) {
    fprintf(stderr, "无法创建:'%s'\n", bootimg);
    return 1;
  }

  if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
    goto fail;
  if (write_padding(fd, pagesize, sizeof(hdr)))
    goto fail;

  if (write(fd, kernel_data, hdr.kernel_size) != (signed)hdr.kernel_size)
    goto fail;
  if (write_padding(fd, pagesize, hdr.kernel_size))
    goto fail;
  if (write(fd, ramdisk_data, hdr.ramdisk_size) != (signed)hdr.ramdisk_size)
    goto fail;
  if (write_padding(fd, pagesize, hdr.ramdisk_size))
    goto fail;

  if (second_data) {
    if (write(fd, second_data, hdr.second_size) != (signed)hdr.second_size)
      goto fail;
    if (write_padding(fd, pagesize, hdr.ramdisk_size))
      goto fail;
  }
  if (dt_data) {
    if (write(fd, dt_data, hdr.dt_size) != hdr.dt_size)
      goto fail;
    if (write_padding(fd, pagesize, hdr.dt_size))
      goto fail;
  }

  return 0;

fail:
  unlink(bootimg);
  close(fd);
  fprintf(stderr, "error: failed writing '%s': %s\n", bootimg,
          strerror(errno));
  return 1;
}
Beispiel #20
0
int main(int argc, char **argv)
{
    boot_img_hdr_v2 hdr;

    char *kernel_fn = NULL;
    void *kernel_data = NULL;
    char *ramdisk_fn = NULL;
    void *ramdisk_data = NULL;
    char *second_fn = NULL;
    void *second_data = NULL;
    char *dtb_fn = NULL;
    void *dtb_data = NULL;
    char *recovery_dtbo_fn = NULL;
    void *recovery_dtbo_data = NULL;
    char *cmdline = "";
    char *bootimg = NULL;
    char *board = "";
    int os_version = 0;
    int os_patch_level = 0;
    int header_version = 0;
    char *dt_fn = NULL;
    void *dt_data = NULL;
    uint32_t pagesize = 2048;
    int fd;
    uint32_t base           = 0x10000000U;
    uint32_t kernel_offset  = 0x00008000U;
    uint32_t ramdisk_offset = 0x01000000U;
    uint32_t second_offset  = 0x00f00000U;
    uint32_t tags_offset    = 0x00000100U;
    uint32_t kernel_sz      = 0;
    uint32_t ramdisk_sz     = 0;
    uint32_t second_sz      = 0;
    uint32_t dt_sz          = 0;
    uint32_t rec_dtbo_sz    = 0;
    uint64_t rec_dtbo_offset= 0;
    uint32_t header_sz      = 0;
    uint32_t dtb_sz         = 0;
    uint64_t dtb_offset     = 0x01f00000U;

    size_t cmdlen;
    enum hash_alg hash_alg = HASH_SHA1;

    argc--;
    argv++;

    memset(&hdr, 0, sizeof(hdr));

    bool get_id = false;
    while(argc > 0){
        char *arg = argv[0];
        if(!strcmp(arg, "--id")) {
            get_id = true;
            argc -= 1;
            argv += 1;
        } else if(argc >= 2) {
            char *val = argv[1];
            argc -= 2;
            argv += 2;
            if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
                bootimg = val;
            } else if(!strcmp(arg, "--kernel")) {
                kernel_fn = val;
            } else if(!strcmp(arg, "--ramdisk")) {
                ramdisk_fn = val;
            } else if(!strcmp(arg, "--second")) {
                second_fn = val;
            } else if(!strcmp(arg, "--dtb")) {
                dtb_fn = val;
            } else if(!strcmp(arg, "--recovery_dtbo") || !strcmp(arg, "--recovery_acpio")) {
                recovery_dtbo_fn = val;
            } else if(!strcmp(arg, "--cmdline")) {
                cmdline = val;
            } else if(!strcmp(arg, "--base")) {
                base = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--kernel_offset")) {
                kernel_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--ramdisk_offset")) {
                ramdisk_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--second_offset")) {
                second_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--tags_offset")) {
                tags_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--dtb_offset")) {
                dtb_offset = strtoul(val, 0, 16);
            } else if(!strcmp(arg, "--board")) {
                board = val;
            } else if(!strcmp(arg,"--pagesize")) {
                pagesize = strtoul(val, 0, 10);
                if((pagesize != 2048) && (pagesize != 4096)
                    && (pagesize != 8192) && (pagesize != 16384)
                    && (pagesize != 32768) && (pagesize != 65536)
                    && (pagesize != 131072)) {
                    fprintf(stderr,"error: unsupported page size %d\n", pagesize);
                    return -1;
                }
            } else if(!strcmp(arg, "--dt")) {
                dt_fn = val;
            } else if(!strcmp(arg, "--os_version")) {
                os_version = parse_os_version(val);
            } else if(!strcmp(arg, "--os_patch_level")) {
                os_patch_level = parse_os_patch_level(val);
            } else if(!strcmp(arg, "--header_version")) {
                header_version = strtoul(val, 0, 10);
            } else if(!strcmp(arg, "--hash")) {
                hash_alg = parse_hash_alg(val);
                if(hash_alg == HASH_UNKNOWN) {
                    fprintf(stderr, "error: unknown hash algorithm '%s'\n", val);
                    return -1;
                }
            } else {
                return usage();
            }
        } else {
            return usage();
        }
    }
    hdr.page_size = pagesize;

    hdr.kernel_addr =  base + kernel_offset;
    hdr.ramdisk_addr = base + ramdisk_offset;
    hdr.second_addr =  base + second_offset;
    hdr.tags_addr =    base + tags_offset;

    hdr.header_version = header_version;
    hdr.os_version = (os_version << 11) | os_patch_level;

    if(bootimg == 0) {
        fprintf(stderr,"error: no output filename specified\n");
        return usage();
    }

    if(kernel_fn == 0) {
        fprintf(stderr,"error: no kernel image specified\n");
        return usage();
    }

    if(strlen(board) >= BOOT_NAME_SIZE) {
        fprintf(stderr,"error: board name too large\n");
        return usage();
    }

    strcpy((char *) hdr.name, board);

    memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);

    cmdlen = strlen(cmdline);
    if(cmdlen <= BOOT_ARGS_SIZE) {
        strcpy((char *)hdr.cmdline, cmdline);
    } else if(cmdlen <= BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE) {
        /* exceeds the limits of the base command-line size, go for the extra */
        memcpy(hdr.cmdline, cmdline, BOOT_ARGS_SIZE);
        strcpy((char *)hdr.extra_cmdline, cmdline+BOOT_ARGS_SIZE);
    } else {
        fprintf(stderr,"error: kernel commandline too large\n");
        return 1;
    }

    kernel_data = load_file(kernel_fn, &kernel_sz);
    if(kernel_data == 0) {
        fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn);
        return 1;
    }
    hdr.kernel_size = kernel_sz;

    if(ramdisk_fn == NULL) {
        ramdisk_data = 0;
    } else {
        ramdisk_data = load_file(ramdisk_fn, &ramdisk_sz);
        if(ramdisk_data == 0) {
            fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn);
            return 1;
        }
    }
    hdr.ramdisk_size = ramdisk_sz;

    if(second_fn) {
        second_data = load_file(second_fn, &second_sz);
        if(second_data == 0) {
            fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn);
            return 1;
        }
    }
    hdr.second_size = second_sz;

    if(header_version == 0) {
        if(dt_fn) {
            dt_data = load_file(dt_fn, &dt_sz);
            if(dt_data == 0) {
                fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn);
                return 1;
            }
        }
        hdr.dt_size = dt_sz; /* overrides hdr.header_version */
    } else {
        if(recovery_dtbo_fn) {
            recovery_dtbo_data = load_file(recovery_dtbo_fn, &rec_dtbo_sz);
            if(recovery_dtbo_data == 0) {
                fprintf(stderr,"error: could not load recovery dtbo image '%s'\n", recovery_dtbo_fn);
                return 1;
            }
            /* header occupies a page */
            rec_dtbo_offset = pagesize * (1 + \
                                          (kernel_sz + pagesize - 1) / pagesize + \
                                          (ramdisk_sz + pagesize - 1) / pagesize + \
                                          (second_sz + pagesize - 1) / pagesize);
        }
        if(header_version == 1) {
            header_sz = 1648;
        } else {
            header_sz = sizeof(hdr);
        }
        if(header_version > 1) {
            if(dtb_fn) {
                dtb_data = load_file(dtb_fn, &dtb_sz);
                if(dtb_data == 0) {
                    fprintf(stderr,"error: could not load recovery dtb image '%s'\n", dtb_fn);
                    return 1;
                }
            }
        }
    }
    hdr.recovery_dtbo_size = rec_dtbo_sz;
    hdr.recovery_dtbo_offset = rec_dtbo_offset;
    hdr.header_size = header_sz;
    hdr.dtb_size = dtb_sz;
    if(header_version > 1) {
        hdr.dtb_addr = base + dtb_offset;
    } else {
        hdr.dtb_addr = 0;
    }

    /* put a hash of the contents in the header so boot images can be
     * differentiated based on their first 2k.
     */
    generate_id(hash_alg, &hdr, kernel_data, ramdisk_data, second_data, dt_data, recovery_dtbo_data, dtb_data);

    fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644);
    if(fd < 0) {
        fprintf(stderr,"error: could not create '%s'\n", bootimg);
        return 1;
    }

    if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;
    if(write_padding(fd, pagesize, sizeof(hdr))) goto fail;

    if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail;
    if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail;

    if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail;
    if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;

    if(second_data) {
        if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail;
        if(write_padding(fd, pagesize, hdr.second_size)) goto fail;
    }

    if(dt_data) {
        if(write(fd, dt_data, hdr.dt_size) != (ssize_t) hdr.dt_size) goto fail;
        if(write_padding(fd, pagesize, hdr.dt_size)) goto fail;
    } else {
        if(recovery_dtbo_data) {
            if(write(fd, recovery_dtbo_data, hdr.recovery_dtbo_size) != (ssize_t) hdr.recovery_dtbo_size) goto fail;
            if(write_padding(fd, pagesize, hdr.recovery_dtbo_size)) goto fail;
        }
        if(dtb_data) {
            if(write(fd, dtb_data, hdr.dtb_size) != (ssize_t) hdr.dtb_size) goto fail;
            if(write_padding(fd, pagesize, hdr.dtb_size)) goto fail;
        }
    }

    if(get_id) {
        print_id((uint8_t *) hdr.id, sizeof(hdr.id));
    }
    return 0;

fail:
    unlink(bootimg);
    close(fd);
    fprintf(stderr,"error: failed writing '%s': %s\n", bootimg,
            strerror(errno));
    return 1;
}
Beispiel #21
0
static bool write_fixed_files()
{
  int cur_input,cur_output;
  unsigned long bytes_have,bytes_needed,bytes_to_xfer;
  char outfilename[FILENAME_SIZE];
  bool success;
  progress_info proginfo;

  success = FALSE;

  cur_input = cur_output = 0;
  bytes_have = (unsigned long)files[cur_input]->data_size;
  bytes_needed = (unsigned long)files[cur_output]->new_data_size;

  proginfo.initialized = FALSE;
  proginfo.prefix = "Fixing";
  proginfo.clause = "-->";
  proginfo.filename1 = files[0]->filename;
  proginfo.filedesc1 = files[0]->m_ss;
  proginfo.filename2 = NULL;
  proginfo.filedesc2 = NULL;
  proginfo.bytes_total = 1;

  if (!open_this_file(cur_output,outfilename,&proginfo))
    goto cleanup;

  if (!reopen_input_file(cur_input,&proginfo))
    goto cleanup;

  while (cur_input < numfiles && cur_output < numfiles) {
    bytes_to_xfer = min(bytes_have,bytes_needed);

    if (transfer_n_bytes(files[cur_input]->input,files[cur_output]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) {
      prog_error(&proginfo);
      st_warning("error while transferring %lu bytes of data",bytes_to_xfer);
      goto cleanup;
    }

    bytes_have -= bytes_to_xfer;
    bytes_needed -= bytes_to_xfer;

    if (0 == bytes_have) {
      close_input_stream(files[cur_input]);
      files[cur_input]->input = NULL;
      cur_input++;
      if (cur_input < numfiles) {
        bytes_have = (unsigned long)files[cur_input]->data_size;

        if (!reopen_input_file(cur_input,&proginfo))
          goto cleanup;
      }
    }

    if (0 == bytes_needed) {
      prog_success(&proginfo);

      if (numfiles - 1 == cur_output) {
        if (pad) {
          if (pad_bytes) {
            if (pad_bytes != write_padding(files[cur_output]->output,pad_bytes,NULL)) {
              prog_error(&proginfo);
              st_warning("error while padding with %d zero-bytes",pad_bytes);
              goto cleanup;
            }
            st_info("Padded last file with %d zero-bytes.\n",pad_bytes);
          }
          else
            st_info("No padding needed.\n");
        }
        else {
          st_info("Last file was not padded, ");
          if (pad_bytes)
            st_info("though it needs %d bytes of padding.\n",pad_bytes);
          else
            st_info("nor was it needed.\n");

          if ((files[cur_output]->new_data_size & 1) && (1 != write_padding(files[cur_output]->output,1,NULL))) {
            prog_error(&proginfo);
            st_warning("error while NULL-padding odd-sized data chunk");
            goto cleanup;
          }
        }
      }

      close_output_stream(files[cur_output]);
      files[cur_output]->output = NULL;
      cur_output++;
      if (cur_output < numfiles) {
        bytes_needed = (unsigned long)files[cur_output]->new_data_size;

        if (!open_this_file(cur_output,outfilename,&proginfo))
          goto cleanup;
      }
    }
  }

  success = TRUE;

cleanup:
  if (!success) {
    close_output_stream(files[cur_output]);
    remove_file(outfilename);
    st_error("failed to fix files");
  }

  return success;
}
static bool split_file(wave_info *info)
{
  unsigned char header[CANONICAL_HEADER_SIZE];
  char outfilename[FILENAME_SIZE],filenum[FILENAME_SIZE];
  int current;
  wint discard,bytes;
  bool success;
  wlong leadin_bytes, leadout_bytes, bytes_to_xfer;
  progress_info proginfo;
 
  // uwe
  double start_time, end_time, last_end_time;	
  
	
  success = FALSE;

  proginfo.initialized = FALSE;
  proginfo.prefix = "Splitting";
  proginfo.clause = "-->";
  proginfo.filename1 = info->filename;
  proginfo.filedesc1 = info->m_ss;
  proginfo.filename2 = NULL;
  proginfo.filedesc2 = NULL;
  proginfo.bytes_total = 0;

  if (!open_input_stream(info)) {
    prog_error(&proginfo);
    st_error("could not reopen input file: [%s]",info->filename);
  }

  discard = info->header_size;
  while (discard > 0) {
    bytes = min(discard,CANONICAL_HEADER_SIZE);
    if (read_n_bytes(info->input,header,bytes,NULL) != bytes) {
      prog_error(&proginfo);
      st_error("error while discarding %d-byte WAVE header",info->header_size);
    }
    discard -= bytes;
  }

  leadin_bytes = (leadin) ? smrt_parse((unsigned char *)leadin,info) : 0;
  leadout_bytes = (leadout) ? smrt_parse((unsigned char *)leadout,info) : 0;
  adjust_for_leadinout(leadin_bytes,leadout_bytes);

  // uwe transcription
  st_output("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
  st_output("<Trans version=\"2\">\n\n");
  start_time = end_time = last_end_time = 0;
	
  for (current=0;current<numfiles;current++) {
    if (SPLIT_INPUT_CUE == input_type && cueinfo.format) {
      create_output_filename(cueinfo.filenames[current],"",outfilename);
    }
    else {
      st_snprintf(filenum,8,num_format,current+offset);
      create_output_filename(filenum,"",outfilename);
    }

    files[current]->chunk_size = files[current]->data_size + CANONICAL_HEADER_SIZE - 8;
    files[current]->channels = info->channels;
    files[current]->samples_per_sec = info->samples_per_sec;
    files[current]->avg_bytes_per_sec = info->avg_bytes_per_sec;
    files[current]->block_align = info->block_align;
    files[current]->bits_per_sample = info->bits_per_sample;
    files[current]->wave_format = info->wave_format;
    files[current]->rate = info->rate;
    files[current]->length = files[current]->data_size / (wlong)info->rate;
    files[current]->exact_length = (double)files[current]->data_size / (double)info->rate;
    files[current]->total_size = files[current]->chunk_size + 8;

    length_to_str(files[current]);

    proginfo.filedesc2 = files[current]->m_ss;
    proginfo.bytes_total = files[current]->total_size;

    if (extract_track[current]) {
      proginfo.prefix = "Splitting";
      proginfo.filename2 = outfilename;

	  // uwe transcription
	  start_time += last_end_time;
	  end_time += files[current]->data_size / (wlong)info->rate;
	  last_end_time = end_time;
		
	  printf("<Turn startTime=\"%.2f\"", start_time); // %.2f
	  st_output(" endTime=\"%.2f\"", end_time);
	  st_output(" splitFilename=\"%s\"", outfilename);
	  st_output(" speaker=\"spk1\">\n");
	  st_output("<Sync time=\"%.2f\"/>\n", start_time);
	  st_output("***Include transcript words here***\n");
	  st_output("</Turn>\n");
		
      if (NULL == (files[current]->output = open_output_stream(outfilename,&files[current]->output_proc))) {
        prog_error(&proginfo);
        st_error("could not open output file");
      }
    }
    else {
      proginfo.prefix = "Skipping ";
      proginfo.filename2 = NULLDEVICE;

      if (NULL == (files[current]->output = open_output(NULLDEVICE))) {
        prog_error(&proginfo);
        st_error("while skipping track %d: could not open output file: [%s]",current+1,NULLDEVICE);
      }

      files[current]->output_proc.pid = NO_CHILD_PID;
    }

    if (PROB_ODD_SIZED_DATA(files[current]))
      files[current]->chunk_size++;

    make_canonical_header(header,files[current]);

	// uwe disable
    //prog_update(&proginfo);

    if (write_n_bytes(files[current]->output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) {
      prog_error(&proginfo);
      st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE);
      goto cleanup;
    }

    /* if this is not the first file, finish up writing previous file, and simultaneously start writing to current file */
    if (0 != current) {
      /* write overlapping lead-in/lead-out data to both previous and current files */
      if (transfer_n_bytes2(info->input,files[current]->output,files[current-1]->output,leadin_bytes+leadout_bytes,&proginfo) != leadin_bytes+leadout_bytes) {
        prog_error(&proginfo);
        st_warning("error while transferring %ld bytes of lead-in/lead-out",leadin_bytes+leadout_bytes);
        goto cleanup;
      }

      /* pad and close previous file */
      if (PROB_ODD_SIZED_DATA(files[current-1]) && (1 != write_padding(files[current-1]->output,1,&proginfo))) {
        prog_error(&proginfo);
        st_warning("error while NULL-padding odd-sized data chunk");
        goto cleanup;
      }

      close_output(files[current-1]->output,files[current-1]->output_proc);
    }

    /* transfer unique non-overlapping data from input file to current file */
    bytes_to_xfer = files[current]->new_data_size;
    if (0 != current)
      bytes_to_xfer -= leadout_bytes;
    if (numfiles - 1 != current)
      bytes_to_xfer -= leadin_bytes;

    if (transfer_n_bytes(info->input,files[current]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) {
      prog_error(&proginfo);
      st_warning("error while transferring %ld bytes of data",bytes_to_xfer);
      goto cleanup;
    }

    /* if this is the last file, close it */
    if (numfiles - 1 == current) {
      /* pad and close current file */
      if (PROB_ODD_SIZED_DATA(files[current]) && (1 != write_padding(files[current]->output,1,&proginfo))) {
        prog_error(&proginfo);
        st_warning("error while NULL-padding odd-sized data chunk");
        goto cleanup;
      }

      close_output(files[current]->output,files[current]->output_proc);

      // uwe transcription  
      st_output("</Trans>\n");

    }

	// uwe disable 
    // prog_success(&proginfo);
 
  }

  close_input_stream(info);

  success = TRUE;

cleanup:
  if (!success) {
    close_output(files[current]->output,files[current]->output_proc);
    remove_file(outfilename);
    st_error("failed to split file");
  }

  return success;
}
Beispiel #23
0
/* Adapted from libavformat/spdifenc.c:
 * It seems Dolby TrueHD frames have to be encapsulated in MAT frames before
 * they can be encapsulated in IEC 61937.
 * Here we encapsulate 24 TrueHD frames in a single MAT frame, padding them
 * to achieve constant rate.
 * The actual format of a MAT frame is unknown, but the below seems to work.
 * However, it seems it is not actually necessary for the 24 TrueHD frames to
 * be in an exact alignment with the MAT frame
 */
static int write_buffer_truehd( filter_t *p_filter, block_t *p_in_buf )
{
#define TRUEHD_FRAME_OFFSET     2560

    filter_sys_t *p_sys = p_filter->p_sys;

    if( !p_sys->p_out_buf
     && write_init( p_filter, p_in_buf, 61440, 61440 / 16 ) )
        return SPDIF_ERROR;

    int i_padding = 0;
    if( p_sys->truehd.i_frame_count == 0 )
    {
        static const char p_mat_start_code[20] = {
            0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00,
            0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0
        };
        write_data( p_filter, p_mat_start_code, 20, true );
        /* We need to include the S/PDIF header in the first MAT frame */
        i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - 20
                  - SPDIF_HEADER_SIZE;
    }
    else if( p_sys->truehd.i_frame_count == 11 )
    {
        /* The middle mat code need to be at the ((2560 * 12) - 4) offset */
        i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - 4;
    }
    else if( p_sys->truehd.i_frame_count == 12 )
    {
        static const char p_mat_middle_code[12] = {
            0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA,
            0x82, 0x83, 0x49, 0x80, 0x77, 0xE0
        };
        write_data( p_filter, p_mat_middle_code, 12, true );
        i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - ( 12 - 4 );
    }
    else if( p_sys->truehd.i_frame_count == 23 )
    {
        static const char p_mat_end_code[16] = {
            0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11
        };

        /* The end mat code need to be at the ((2560 * 24) - 24) offset */
        i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer - 24;

        if( i_padding < 0 || p_in_buf->i_buffer + i_padding >
            p_sys->p_out_buf->i_buffer - p_sys->i_out_offset )
            return SPDIF_ERROR;

        write_buffer( p_filter, p_in_buf );
        write_padding( p_filter, i_padding );
        write_data( p_filter, p_mat_end_code, 16, true );
        write_finalize( p_filter, IEC61937_TRUEHD, 1 /* in bytes */ );
        p_sys->truehd.i_frame_count = 0;
        return SPDIF_SUCCESS;
    }
    else
        i_padding = TRUEHD_FRAME_OFFSET - p_in_buf->i_buffer;

    if( i_padding < 0 || p_in_buf->i_buffer + i_padding >
        p_sys->p_out_buf->i_buffer - p_sys->i_out_offset )
        return SPDIF_ERROR;

    write_buffer( p_filter, p_in_buf );
    write_padding( p_filter, i_padding );
    p_sys->truehd.i_frame_count++;
    return SPDIF_MORE_DATA;
}