home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------------------ */
- /* */
- /* Developed by: Vijayakumar Rangarajan */
- /* Name: writetag.c */
- /* Function: Allows insertion of a new tag into the */
- /* existing field list/ update of the existing */
- /* tag value */
- /* 9/22 Original, backedup as writetag.ins, works with all *.ins */
- /* 10.10 pm with write_tags, and 'far' pointers in write_fields. */
- /* */
- /* 9/22 */
- /* 10.25 New change to support direct file creation with write_tags */
- /* without prior to write_fields. */
- /* */
- /* ------------------------------------------------------------------ */
-
- #include "tifstruc.h"
-
- extern long set_position();
- extern long get_cpos();
- extern int write_data();
- extern int header_write();
- extern int header_rewrite();
- extern int field_data_write();
- extern ifdstrc subfile, strpofst, strpbtcnt;
- void new_check_tag();
- extern void init_tif_hdr();
- extern char tag_273;
- extern char tag_279;
- extern long field_data_pos;
- extern long field_data_endpos;
- extern long header_fil1_pos;
- extern long ifdsize;
- extern long next_val_pos;
- extern short fields_exist;
- extern short image_begin;
- extern long get_tagval();
- extern int find_type();
- extern short rewrite_field_data();
- extern int write_tag_val();
- extern short field_mem_tab[];
- extern int tot_tag_num;
-
- void build_sbfile_tag();
-
- short field_mem_tab1[256];
-
-
-
- static short *field_cur_ptr;
- static short *temp_field_cur_ptr;
- static short build_tag_mem[6];
- static short *new_tag_ptr;
- static short *new_tag_pos;
- static short new_tag_index;
-
- static unsigned bytsize = 12; /* tag byte size = 12 */
-
- short *build_one_tag(), find_len(), find_tag_pos(), update_temp_list();
-
- int write_tag(filehndl, fdtype, tagnum, dataptr, length)
-
- int filehndl;
- short fdtype;
- short tagnum;
- short far *dataptr;
- short length;
-
- {
- static int leng;
- static short total_tag;
- static long fdsize;
- static long next_ifd_ptr;
- long *ptr;
-
- /* if already a list of tags exist, then check if insertion/update */
-
- if (fields_exist)
- {
- tot_tag_num = field_mem_tab[0];
- fdsize = (2+(tot_tag_num * 12));
- leng = (int)fdsize;
- memcpy ( field_mem_tab1, field_mem_tab, leng);
- if (get_tagval(tagnum) <= 0)
-
- {
- if (image_begin) /* no insertion after image */
- return(0); /* write*/
-
- field_cur_ptr = (short *) field_mem_tab;
- temp_field_cur_ptr = (short *) field_mem_tab1;
-
- /* Check if stripbytcount and stripoffset tags to be included */
- /* check_tag(tagnum, temp_field_cur_ptr); */
-
- /* Build the tag data structure for the specified tag */
-
- if((new_tag_ptr = build_one_tag(filehndl, tagnum, dataptr, fdtype, length)) <= 0)
- return (0);
-
- /* Find the position of the tag to be written in the existing field list */
-
- if((new_tag_index = find_tag_pos(tagnum, field_mem_tab1)) < 0)
-
- {
- new_tag_index = field_mem_tab1[0];
- }
-
- new_tag_pos = ((field_mem_tab1 +1) + (new_tag_index * 6));
-
- temp_field_cur_ptr = new_tag_pos;
- new_check_tag(tagnum, temp_field_cur_ptr);
- new_tag_pos = temp_field_cur_ptr;
-
- /* Write the new tag data structure into the temp field list */
-
- memcpy( new_tag_pos, new_tag_ptr, bytsize);
-
- /* Advance the pointer in the new field buffer */
-
- new_tag_pos += (bytsize/2);
-
- /* Append the remaining tags from the original field list to the new list */
-
- if(new_tag_index >= 0)
- {
- if(update_temp_list(field_mem_tab, new_tag_pos, new_tag_index) <= 0)
- return(0);
- }
-
- /* Update the total tag number in the new field */
-
- tot_tag_num++;
- field_mem_tab1[0] = (short) tot_tag_num;
- fdsize = (2+(tot_tag_num * 12));
- temp_field_cur_ptr = field_mem_tab1;
- temp_field_cur_ptr += (fdsize/2);
- next_ifd_ptr = 0;
- ptr = (long *) temp_field_cur_ptr;
- *ptr = next_ifd_ptr;
- fdsize +=4;
- leng = (int) fdsize;
-
- /* Copy the updated temp field list to the actual field data buffer */
-
- memcpy( field_mem_tab, field_mem_tab1, leng);
-
- /* Rewrite the field data, onto the file */
-
- /* field_data_pos = next_val_pos; */
-
- ifdsize = fdsize;
- if (rewrite_field_data(filehndl) < 0)
- return(0);
-
- field_data_endpos = get_cpos(filehndl);
-
- /* Update the first ifd pointer in the header and rewrite the header */
-
- tiff_header.first_ifd_addr = field_data_pos;
- if(header_rewrite(filehndl, header_fil1_pos) < 0)
- return(0);
-
-
- return(1);
-
- }
-
- /* The specified tag already exists in the field list, just update the value */
-
- else
-
- {
-
- /* Update the tag value, use old 'write_tag' function */
-
- if(write_tag_val(filehndl, fdtype, tagnum, dataptr, length) <= 0)
- return(0);
-
- return(1);
-
- }
-
- }
-
- /* No fields exist, create a new field structure - a new file */
-
- else
-
- {
-
- /* Create new fields with the new header */
-
- fields_exist = 1;
- tot_tag_num = 0;
- ifdsize = 0;
- init_tif_hdr();
- header_fil1_pos = get_cpos(filehndl);
- if (header_write(filehndl) < 0)
- return(0);
-
- next_val_pos = get_cpos(filehndl);
-
- field_cur_ptr = (short *) field_mem_tab;
- build_sbfile_tag(fdtype);
- tot_tag_num++;
- memcpy (&(field_mem_tab[1]), &subfile, sizeof(ifdstrc));
- field_cur_ptr += 7;
-
-
- if ((new_tag_ptr = build_one_tag(filehndl, tagnum, dataptr, fdtype,
- length)) <= 0)
- return(0);
-
- field_data_pos = next_val_pos;
- tot_tag_num++;
- ifdsize = (2 + (tot_tag_num * 12));
- memcpy(field_cur_ptr, build_tag_mem, bytsize);
- field_mem_tab[0] = (short)tot_tag_num;
- field_cur_ptr = field_mem_tab;
- field_cur_ptr += (ifdsize/2);
- next_ifd_ptr = 0;
- ptr = (long *) field_cur_ptr;
- *ptr = next_ifd_ptr;
- ifdsize += 4;
- if (field_data_write(filehndl, ifdsize) < 0)
- return(0);
- tiff_header.first_ifd_addr = field_data_pos;
- if (header_rewrite(filehndl, header_fil1_pos) < 0)
- return(0);
-
-
-
- return(1);
-
- }
-
- }
-
-
- /* --------------------------------------------- */
- /* */
- /* Build one tag data structure in build_tag_mem */
- /* */
- /* returns: pointer to the buffer */
- /* */
- /* --------------------------------------------- */
-
-
- short *build_one_tag(filehand, tagno, pointr, filtype, siz_bytes)
-
- short filehand;
- short tagno;
- short far *pointr;
- short filtype;
- short siz_bytes;
-
- {
-
- short *to_ptr;
- short field_type;
- short data_length;
- long field_length, *ptr;
- char *cptr;
- char far *bptr;
-
- if ((field_type = find_type(tagno)) < 0)
- return((short *)-1);
-
- to_ptr = build_tag_mem;
- *to_ptr++ = tagno;
- *to_ptr++ = field_type;
-
- if((data_length = find_len(field_type)) <= 0)
- return((short *)-1);
-
- field_length = (long) ((siz_bytes + data_length -1)/data_length);
- ptr = (long *) to_ptr;
- *ptr++ = field_length;
- to_ptr = (short *) ptr;
-
- /* if(data_length <= 4) */
- if(siz_bytes <= 4)
-
- {
- cptr = (char *) to_ptr;
- bptr = (char far *) pointr;
- while (siz_bytes-- > 0)
- {
- *cptr++ = *bptr++;
- }
- to_ptr = (short *) cptr;
-
- }
-
-
- else
-
- {
-
- if(set_position(filehand, next_val_pos) < 0)
- return(0);
- if (write_data(filehand, pointr, siz_bytes) < 0)
- return(0);
- ptr = (long *) to_ptr;
- *ptr = next_val_pos;
- next_val_pos = get_cpos(filehand);
- field_data_pos = next_val_pos; /* 9/29 */
- }
-
- return (to_ptr = build_tag_mem);
-
- }
-
-
- /* ---------------------------- */
- /* Find_len function */
- /* Returns length in bytes for */
- /* the specified field_type */
- /* ---------------------------- */
-
- short find_len(fld_type)
-
- short fld_type;
-
- {
- short data_len;
-
- switch (fld_type)
-
- {
- case 1:
-
- data_len = 1;
- break;
-
- case 2:
-
- data_len = 1;
- break;
-
- case 3:
-
- data_len = 2;
- break;
-
- case 4:
-
- data_len = 4;
- break;
-
- case 5:
-
- data_len = 8;
- break;
-
- default:
-
- data_len = 0;
-
- }
-
- return (data_len);
-
- }
-
-
-
-
-
- /* --------------------------------------- */
- /* */
- /* Function: Find tag position within the */
- /* new field list for the new */
- /* tag to be inserted */
- /* */
- /* Return: Tag position number in the */
- /* buffer */
- /* --------------------------------------- */
-
-
- short find_tag_pos(tagnmr, field_mem)
-
- short tagnmr;
- short *field_mem;
-
- {
-
- short tag_index = 0;
- short number_of_tags;
- short *field_pointr;
-
- number_of_tags = *field_mem++;
- field_pointr = field_mem;
- while (number_of_tags-- > 0)
- {
- if (tagnmr > *field_pointr)
- {
- field_pointr += 6;
- tag_index += 1;
- }
- else
- {
- return(tag_index);
- }
- }
-
- return (-1);
-
- }
-
-
- /* -------------------------------------- */
- /* Function: Append the remaining existing*/
- /* tag list to the new tag list */
- /* after the insertion of the */
- /* new tag. */
- /* */
- /* Return: status */
- /* */
- /* -------------------------------------- */
-
-
- short update_temp_list(exist_field, new_field, tag_index)
-
- short *exist_field;
- short *new_field;
- short tag_index;
-
- {
-
- short *from_ptr;
- short *to_ptr;
- short total_tags;
- short i;
- unsigned bytecount;
-
- total_tags = *exist_field++;
- from_ptr = (exist_field + (tag_index * 6));
- to_ptr = new_field;
- i = (total_tags - (tag_index)); /* because index begins from 0 */
-
- bytecount = (i * 12);
-
- /* update the total tag byte count by 12 more bytes */
-
- ifdsize += 12;
-
- memcpy(to_ptr, from_ptr, bytecount);
-
- return(1);
-
- }
-
-
-
-
- /* Check the tag if stripoffset / stripbytecount tags are to be attached */
-
- void new_check_tag(tag_num, field_ptr)
- short tag_num;
- short *field_ptr;
-
- {
- void new_build_strpofst_tag(), new_build_strpbytcnt_tag();
-
- if (tag_num > TAG273)
-
- {
- if (tag_273 == 0)
- {
- tag_273 = 1;
- new_build_strpofst_tag(field_ptr);
- }
-
- if (tag_num > TAG279)
-
- {
- if (tag_279 == 0)
- {
- tag_279 = 1;
- new_build_strpbytcnt_tag(temp_field_cur_ptr);
- }
- }
- }
-
- }
-
-
- /* Build stripoffset tag */
-
- void new_build_strpofst_tag(field_ptr)
- short *field_ptr;
-
- {
-
- strpofst.tagnum = TAG273;
- strpofst.fieldtype = TLONG;
- strpofst.fieldlen = 0;
- strpofst.offset_rvalue = 0L;
-
- memcpy (field_ptr, &strpofst, sizeof(ifdstrc));
- temp_field_cur_ptr += 6;
- tot_tag_num++;
- }
-
-
-
- /* Build stripbytecount tag */
-
- void new_build_strpbytcnt_tag(field_ptr)
- short *field_ptr;
-
-
- {
-
- strpbtcnt.tagnum = TAG279;
- strpbtcnt.fieldtype = TLONG;
- strpbtcnt.fieldlen = 0;
- strpbtcnt.offset_rvalue = 0L;
-
- memcpy (field_ptr, &strpbtcnt, sizeof(ifdstrc));
- temp_field_cur_ptr += 6;
- tot_tag_num++;
- }
-