+static int packed_object_info(struct packed_git *p, off_t obj_offset,
+ unsigned long *sizep, int *rtype,
+ unsigned long *disk_sizep)
+{
+ struct pack_window *w_curs = NULL;
+ unsigned long size;
+ off_t curpos = obj_offset;
+ enum object_type type;
+
+ type = unpack_object_header(p, &w_curs, &curpos, &size);
+
+ if (rtype)
+ *rtype = type; /* representation type */
+
+ if (sizep) {
+ if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
+ off_t tmp_pos = curpos;
+ off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
+ type, obj_offset);
+ if (!base_offset) {
+ type = OBJ_BAD;
+ goto out;
+ }
+ *sizep = get_size_from_delta(p, &w_curs, tmp_pos);
+ if (*sizep == 0) {
+ type = OBJ_BAD;
+ goto out;
+ }
+ } else {
+ *sizep = size;
+ }
+ }
+
+ if (disk_sizep) {
+ struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
+ *disk_sizep = revidx[1].offset - obj_offset;
+ }
+
+ type = packed_to_object_type(p, obj_offset, type, &w_curs, curpos);
+
+out:
+ unuse_pack(&w_curs);
+ return type;
+}
+