zip_close_archive_file(gx_device_xps *xps_dev, const char *filename)
{
    gx_device_xps_zinfo_t *info = zip_look_up_file_info(xps_dev, filename);
    gx_device_xps_zdata_t data;
    byte buf[4];
    unsigned long crc = 0;
    int count = 0;
    int len;
    /* we can't use the vector stream accessor because it calls beginpage */
    stream *f = ((gx_device_vector*)xps_dev)->strm;

    if (info == NULL)
        return -1;

    /* Already stored */
    if (info->saved)
        return 0;

    data = info->data;
    if ((int)data.count >= 0) {
        gp_file *fp = data.fp;
        uint nread;

        if (fp == NULL)
            return gs_throw_code(gs_error_Fatal);

        crc = crc32(0L, Z_NULL, 0);
        gp_rewind(fp);
        while (!gp_feof(fp)) {
            nread = gp_fread(buf, 1, sizeof(buf), fp);
            crc = crc32(crc, buf, nread);
            count = count + nread;
        }
        /* If this is a TIFF file, then update the data count information.
           During the writing of the TIFF directory there is seeking and
           relocations that occur, which make data.count incorrect. 
           We could just do this for all the files and avoid the test. */
        len = strlen(filename);
        if (len > 3 && (strncmp("tif", &(filename[len - 3]), 3) == 0)) {
            info->data.count = count;
            data = info->data;
            data.fp = fp;
        }
    }

    info->current_pos = stell(f);
    info->CRC = crc;

    /* NB should use ghostscript "gp" time and date functions for
       this, for now we hardwire the dates. */
    info->date = make_dos_date(2012, 2, 16);
    info->time = make_dos_time(9, 15, 0);

    put_u32(f, 0x04034b50); /* magic */
    put_u16(f, 20);         /* version */
    put_u16(f, 0);          /* flags */
    put_u16(f, 0);          /* method */
    put_u16(f, info->time);
    put_u16(f, info->date);
    put_u32(f, crc);
    put_u32(f, data.count); /* compressed */
    put_u32(f, data.count); /* uncompressed */
    put_u16(f, strlen(filename));
    put_u16(f, 0);         /* extra field length */
    put_bytes(f, (byte *)filename, strlen(filename));
    {
        gp_file *fp = data.fp;
        gp_rewind(fp);
        while (!gp_feof(fp)) {
                ulong nread = gp_fread(buf, 1, sizeof(buf), fp);
                put_bytes(f, buf, nread);
        }
        gp_fclose(fp);
    }
    put_bytes(f, 0, 0); /* extra field */

    /* Mark as saved */
    info->saved = true;
    return 0;
}
zip_close_archive_file(gx_device_xps *xps_dev, const char *filename)
{
    gx_device_xps_zinfo_t *info = zip_look_up_file_info(xps_dev, filename);
    gx_device_xps_zdata_t data;
    byte buf[4];
    unsigned long crc = 0;
    int count = 0;
    int len;
     
    stream *f = ((gx_device_vector*)xps_dev)->strm;

    if (info == NULL)
        return -1;

     
    if (info->saved)
        return 0;

    data = info->data;
    if ((int)data.count >= 0) {
        gp_file *fp = data.fp;
        uint nread;

        if (fp == NULL)
            return gs_throw_code(gs_error_Fatal);

        crc = crc32(0L, Z_NULL, 0);
        gp_rewind(fp);
        while (!gp_feof(fp)) {
            nread = gp_fread(buf, 1, sizeof(buf), fp);
            crc = crc32(crc, buf, nread);
            count = count + nread;
        }
         
        len = strlen(filename);
        if (len > 3 && (strncmp("tif", &(filename[len - 3]), 3) == 0)) {
            info->data.count = count;
            data = info->data;
            data.fp = fp;
        }
    }

    info->current_pos = stell(f);
    info->CRC = crc;

     
    info->date = make_dos_date(2012, 2, 16);
    info->time = make_dos_time(9, 15, 0);

    put_u32(f, 0x04034b50);  
    put_u16(f, 20);          
    put_u16(f, 0);           
    put_u16(f, 0);           
    put_u16(f, info->time);
    put_u16(f, info->date);
    put_u32(f, crc);
    put_u32(f, data.count);  
    put_u32(f, data.count);  
    put_u16(f, strlen(filename));
    put_u16(f, 0);          
    put_bytes(f, (byte *)filename, strlen(filename));
    {
        gp_file *fp = data.fp;
        gp_rewind(fp);
        while (!gp_feof(fp)) {
                ulong nread = gp_fread(buf, 1, sizeof(buf), fp);
                put_bytes(f, buf, nread);
        }
        gp_fclose(fp);
    }
    put_bytes(f, 0, 0);  

     
    info->saved = true;
    return 0;
}