Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

vp_transpose.c

Go to the documentation of this file.
00001 /*
00002  * vp_transpose.c
00003  *
00004  * Routines to transpose a raw volume.
00005  *
00006  * Copyright (c) 1994 The Board of Trustees of The Leland Stanford
00007  * Junior University.  All rights reserved.
00008  *
00009  * Permission to use, copy, modify and distribute this software and its
00010  * documentation for any purpose is hereby granted without fee, provided
00011  * that the above copyright notice and this permission notice appear in
00012  * all copies of this software and that you do not sell the software.
00013  * Commercial licensing is available by contacting the author.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
00018  *
00019  * Author:
00020  *    Phil Lacroute
00021  *    Computer Systems Laboratory
00022  *    Electrical Engineering Dept.
00023  *    Stanford University
00024  */
00025 
00026 /*
00027  * $Date: 2001/12/17 16:16:23 $
00028  * $Revision: 1.1 $
00029  */
00030 
00031 #include "vp_global.h"
00032 
00033 static int TransposeBlock ANSI_ARGS((void *src, int src_xstride,
00034     int src_ystride, int src_zstride, void *dst, int dst_xstride,
00035     int dst_ystride, int dst_zstride, int xlen, int ylen, int zlen,
00036     int bytes_per_voxel));
00037 
00038 /*
00039  * vpTranspose
00040  *
00041  * Transpose the raw volume data.
00042  */
00043 
00044 vpResult
00045 vpTranspose(vpc, kaxis)
00046 vpContext *vpc; /* context */
00047 int kaxis;      /* axis which will have the largest stride after transposing */
00048 {
00049     void *blk;                  /* buffer to store data during transpose */
00050     int xlen, ylen, zlen;       /* volume size */
00051     int src_xstride, src_ystride, src_zstride; /* strides of src voxels */
00052     int dst_xstride, dst_ystride, dst_zstride; /* strides of dst voxels */
00053     int bytes_per_voxel;        /* size of voxel */
00054     int retcode;
00055 
00056     /* XXX replace with a blocked algorithm to conserve memory and
00057        improve cache performance */
00058 
00059     /* check for errors */
00060     if ((retcode = VPCheckRawVolume(vpc)) != VP_OK)
00061         return(retcode);
00062 
00063     /* decide on the new strides */
00064     xlen = vpc->xlen;
00065     ylen = vpc->ylen;
00066     zlen = vpc->zlen;
00067     src_xstride = vpc->xstride;
00068     src_ystride = vpc->ystride;
00069     src_zstride = vpc->zstride;
00070     bytes_per_voxel = vpc->raw_bytes_per_voxel;
00071     switch (kaxis) {
00072     case VP_X_AXIS:
00073         dst_xstride = ylen*zlen*bytes_per_voxel;
00074         dst_ystride = bytes_per_voxel;
00075         dst_zstride = ylen*bytes_per_voxel;
00076         break;
00077     case VP_Y_AXIS:
00078         dst_xstride = zlen*bytes_per_voxel;
00079         dst_ystride = zlen*xlen*bytes_per_voxel;
00080         dst_zstride = bytes_per_voxel;
00081         break;
00082     case VP_Z_AXIS:
00083         dst_xstride = bytes_per_voxel;
00084         dst_ystride = xlen*bytes_per_voxel;
00085         dst_zstride = xlen*ylen*bytes_per_voxel;
00086         break;
00087     default:
00088         return(VPSetError(vpc, VPERROR_BAD_OPTION));
00089     }
00090     if (src_xstride == dst_xstride && src_ystride == dst_ystride &&
00091         src_zstride == dst_zstride)
00092         return(VP_OK);
00093 
00094     /* transpose volume */
00095     Alloc(vpc, blk, void *, xlen*ylen*zlen*bytes_per_voxel,
00096           "transpose_tmp");
00097     TransposeBlock(vpc->raw_voxels, src_xstride, src_ystride, src_zstride,
00098                    blk, dst_xstride, dst_ystride, dst_zstride,
00099                    xlen, ylen, zlen, bytes_per_voxel);
00100     bcopy(blk, vpc->raw_voxels, xlen*ylen*zlen*bytes_per_voxel);
00101     Dealloc(vpc, blk);
00102     vpc->xstride = dst_xstride;
00103     vpc->ystride = dst_ystride;
00104     vpc->zstride = dst_zstride;
00105     return(VP_OK);
00106 }
00107 
00108 /*
00109  * TransposeBlock
00110  *
00111  * Transpose a block of volume data by copying it from a source array
00112  * to a destination array using the indicated strides.
00113  */
00114 
00115 static int
00116 TransposeBlock(src, src_xstride, src_ystride, src_zstride, dst, dst_xstride,
00117                dst_ystride, dst_zstride, xlen, ylen, zlen, bytes_per_voxel)
00118 void *src;              /* source array */
00119 int src_xstride;        /* strides for source array */
00120 int src_ystride;
00121 int src_zstride;
00122 void *dst;              /* destination array */
00123 int dst_xstride;        /* strides for destination array */
00124 int dst_ystride;
00125 int dst_zstride;
00126 int xlen, ylen, zlen;   /* size of block in voxels per side */
00127 int bytes_per_voxel;    /* size of a voxel */
00128 {
00129     int x, y, z, b;
00130     unsigned char *src_ptr;
00131     unsigned char *dst_ptr;
00132 
00133     src_ptr = src;
00134     dst_ptr = dst;
00135     for (z = 0; z < zlen; z++) {
00136         for (y = 0; y < ylen; y++) {
00137             for (x = 0; x < xlen; x++) {
00138                 for (b = 0; b < bytes_per_voxel; b++)
00139                     dst_ptr[b] = src_ptr[b];
00140                 src_ptr += src_xstride;
00141                 dst_ptr += dst_xstride;
00142             }
00143             src_ptr += src_ystride - xlen*src_xstride;
00144             dst_ptr += dst_ystride - xlen*dst_xstride;
00145         }
00146         src_ptr += src_zstride - ylen*src_ystride;
00147         dst_ptr += dst_zstride - ylen*dst_ystride;
00148     }
00149     return 0 ;  /* RWCox */
00150 }
 

Powered by Plone

This site conforms to the following standards: