
/************************************************************
**  MatrixMemoryAllocate.c
**
**  Object name :
**
**  History :
**     2012.10.24 K.Takagi 新規作成
**
**  Description
**  -----------
**  多次元配列のバッファ確保
**
**  Copyright (c) 2012
**  System In Frontier,Inc.
**  All rights reserved.
**
**  当社の許可なしに複製および転載を禁ず
**
*/

/*=========================================================*/
/*                   Include Files                         */
/*=========================================================*/
#include <stdio.h>
#include <stdlib.h>

/************************************************************
**
**  Public  : 
**
**  History : 2012.10.24 K.Takagi 新規作成
**
**  Description
**  -----------
**  2次元配列のバッファを確保
**    アクセスの効率化のため必要な総容量の1次元配列を確保し、
**    2次元配列へ変換
**
**  メモリ開放は上位ですること（以下の順番で実行）
**    free(data[0])
**    free(data)
**
*/
void **MemoryAllocate2D(int ynum, int xnum, size_t size)
{
    void **data;
    int y;
    
    data = (void **)malloc(sizeof(void *) * ynum);
    if(data == NULL){
        printf("[1] Allocate Error.\n");
        goto ErrEnd1_Allocate2D;
    }
    data[0] = (void *)malloc(size * xnum * ynum);
    if(data[0] == NULL){
        printf("[2] Allocate Error.\n");
        goto ErrEnd2_Allocate2D;
    }
    for(y=1; y<ynum; y++){
        data[y] = data[0] + y * xnum * size;
    }
    return data;

ErrEnd2_Allocate2D:
    free(data);

ErrEnd1_Allocate2D:
    return NULL;
}

/************************************************************
**
**  Public  : 
**
**  History : 2012.10.24 K.Takagi 新規作成
**
**  Description
**  -----------
**  3次元配列のバッファを確保
**    アクセスの効率化のため必要な総容量の1次元配列を確保し、
**    3次元配列へ変換
**
**  メモリ開放は上位ですること（以下の順番で実行）
**    free(data[0][0])
**    free(data[0])
**    free(data)
**
*/
void ***MemoryAllocate3D(int znum, int ynum, int xnum, size_t size)
{
    void ***data;
    int z;
    int y;
    
    data = (void ***)malloc(sizeof(void **) * znum);
    if(data == NULL){
        printf("[1] Allocate Error.\n");
        goto ErrEnd1_Allocate3D;
    }
    data[0] = (void **)malloc(sizeof(void *) * ynum * znum);
    if(data[0] == NULL){
        printf("[2] Allocate Error.\n");
        goto ErrEnd2_Allocate3D;
    }
    for(z=1; z<znum; z++){
        data[z] = &(data[0][z*ynum]);
    }
    data[0][0] = (void *)malloc(size * xnum * ynum * znum);
    if(data[0][0] == NULL){
        printf("[3] Allocate Error.\n");
        goto ErrEnd3_Allocate3D;
    }
    for(y=1; y<ynum*znum; y++){
        data[0][y] = data[0][0] + y * xnum * size;
    }
    return data;

ErrEnd3_Allocate3D:
    free(data[0]);

ErrEnd2_Allocate3D:
    free(data);

ErrEnd1_Allocate3D:
    return NULL;
}

/************************************************************
**
**  Public  : 
**
**  History : 2012.10.24 K.Takagi 新規作成
**
**  Description
**  -----------
**  4次元配列のバッファを確保
**    アクセスの効率化のため必要な総容量の1次元配列を確保し、
**    4次元配列へ変換
**
**  メモリ開放は上位ですること（以下の順番で実行）
**    free(data[0][0][0])
**    free(data[0][0])
**    free(data[0])
**    free(data)
**
*/
void ****MemoryAllocate4D(int wnum, int znum, int ynum, int xnum, size_t size)
{
    void ****data;
    int w;
    int z;
    int y;
    
    data = (void ****)malloc(sizeof(void ***) * wnum);
    if(data == NULL){
        printf("[1] Allocate Error.\n");
        goto ErrEnd1_Allocate4D;
    }
    data[0] = (void ***)malloc(sizeof(void **) * znum * wnum);
    if(data[0] == NULL){
        printf("[2] Allocate Error.\n");
        goto ErrEnd2_Allocate4D;
    }
    for(w=1; w<wnum; w++){
        data[w] = &(data[0][w*znum]);
    }
    data[0][0] = (void **)malloc(sizeof(void *) * ynum * znum * wnum);
    if(data[0][0] == NULL){
        printf("[3] Allocate Error.\n");
        goto ErrEnd3_Allocate4D;
    }
    for(z=1; z<znum*wnum; z++){
        data[0][z] = &(data[0][0][z*ynum]);
    }
    data[0][0][0] = (void *)malloc(size * xnum * ynum * znum * wnum);
    if(data[0][0][0] == NULL){
        printf("[4] Allocate Error.\n");
        goto ErrEnd4_Allocate4D;
    }
    for(y=1; y<ynum*znum*wnum; y++){
        data[0][0][y] = data[0][0][0] + y * xnum * size;
    }
    return data;

ErrEnd4_Allocate4D:
    free(data[0][0]);

ErrEnd3_Allocate4D:
    free(data[0]);

ErrEnd2_Allocate4D:
    free(data);

ErrEnd1_Allocate4D:
    return NULL;
}

/* EOF */
