File: vp_transpose.c

package info (click to toggle)
volpack 1.0b3-10
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 4,864 kB
  • sloc: ansic: 12,208; sh: 9,078; makefile: 90; csh: 76
file content (149 lines) | stat: -rw-r--r-- 4,438 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * vp_transpose.c
 *
 * Routines to transpose a raw volume.
 *
 * Copyright (c) 1994 The Board of Trustees of The Leland Stanford
 * Junior University.  All rights reserved.
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice and this permission notice appear in
 * all copies of this software and that you do not sell the software.
 * Commercial licensing is available by contacting the author.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Author:
 *    Phil Lacroute
 *    Computer Systems Laboratory
 *    Electrical Engineering Dept.
 *    Stanford University
 */

/*
 * $Date: 1994/12/30 23:52:38 $
 * $Revision: 1.18 $
 */

#include "vp_global.h"

static int TransposeBlock ANSI_ARGS((void *src, int src_xstride,
    int src_ystride, int src_zstride, void *dst, int dst_xstride,
    int dst_ystride, int dst_zstride, int xlen, int ylen, int zlen,
    int bytes_per_voxel));

/*
 * vpTranspose
 *
 * Transpose the raw volume data.
 */

vpResult
vpTranspose(vpc, kaxis)
vpContext *vpc;	/* context */
int kaxis;	/* axis which will have the largest stride after transposing */
{
    void *blk;			/* buffer to store data during transpose */
    int xlen, ylen, zlen;	/* volume size */
    int src_xstride, src_ystride, src_zstride; /* strides of src voxels */
    int dst_xstride, dst_ystride, dst_zstride; /* strides of dst voxels */
    int bytes_per_voxel;	/* size of voxel */
    int retcode;

    /* XXX replace with a blocked algorithm to conserve memory and
       improve cache performance */

    /* check for errors */
    if ((retcode = VPCheckRawVolume(vpc)) != VP_OK)
	return(retcode);

    /* decide on the new strides */
    xlen = vpc->xlen;
    ylen = vpc->ylen;
    zlen = vpc->zlen;
    src_xstride = vpc->xstride;
    src_ystride = vpc->ystride;
    src_zstride = vpc->zstride;
    bytes_per_voxel = vpc->raw_bytes_per_voxel;
    switch (kaxis) {
    case VP_X_AXIS:
	dst_xstride = ylen*zlen*bytes_per_voxel;
	dst_ystride = bytes_per_voxel;
	dst_zstride = ylen*bytes_per_voxel;
	break;
    case VP_Y_AXIS:
	dst_xstride = zlen*bytes_per_voxel;
	dst_ystride = zlen*xlen*bytes_per_voxel;
	dst_zstride = bytes_per_voxel;
	break;
    case VP_Z_AXIS:
	dst_xstride = bytes_per_voxel;
	dst_ystride = xlen*bytes_per_voxel;
	dst_zstride = xlen*ylen*bytes_per_voxel;
	break;
    default:
	return(VPSetError(vpc, VPERROR_BAD_OPTION));
    }
    if (src_xstride == dst_xstride && src_ystride == dst_ystride &&
	src_zstride == dst_zstride)
	return(VP_OK);

    /* transpose volume */
    Alloc(vpc, blk, void *, xlen*ylen*zlen*bytes_per_voxel,
	  "transpose_tmp");
    TransposeBlock(vpc->raw_voxels, src_xstride, src_ystride, src_zstride,
		   blk, dst_xstride, dst_ystride, dst_zstride,
		   xlen, ylen, zlen, bytes_per_voxel);
    bcopy(blk, vpc->raw_voxels, xlen*ylen*zlen*bytes_per_voxel);
    Dealloc(vpc, blk);
    vpc->xstride = dst_xstride;
    vpc->ystride = dst_ystride;
    vpc->zstride = dst_zstride;
    return(VP_OK);
}

/*
 * TransposeBlock
 *
 * Transpose a block of volume data by copying it from a source array
 * to a destination array using the indicated strides.
 */

static int
TransposeBlock(src, src_xstride, src_ystride, src_zstride, dst, dst_xstride,
	       dst_ystride, dst_zstride, xlen, ylen, zlen, bytes_per_voxel)
void *src;		/* source array */
int src_xstride;	/* strides for source array */
int src_ystride;
int src_zstride;
void *dst;		/* destination array */
int dst_xstride;	/* strides for destination array */
int dst_ystride;
int dst_zstride;
int xlen, ylen, zlen;	/* size of block in voxels per side */
int bytes_per_voxel;	/* size of a voxel */
{
    int x, y, z, b;
    unsigned char *src_ptr;
    unsigned char *dst_ptr;

    src_ptr = src;
    dst_ptr = dst;
    for (z = 0; z < zlen; z++) {
	for (y = 0; y < ylen; y++) {
	    for (x = 0; x < xlen; x++) {
		for (b = 0; b < bytes_per_voxel; b++)
		    dst_ptr[b] = src_ptr[b];
		src_ptr += src_xstride;
		dst_ptr += dst_xstride;
	    }
	    src_ptr += src_ystride - xlen*src_xstride;
	    dst_ptr += dst_ystride - xlen*dst_xstride;
	}
	src_ptr += src_zstride - ylen*src_ystride;
	dst_ptr += dst_zstride - ylen*dst_ystride;
    }
}