#include #include #include #include #include #include #include #include "etcache.h" #include "easycolor.h" #include "blend.h" #include "accesscache.h" /*****************************************************************************/ /* 構造体EasyColorの内容を表示する(デバッグ用) */ /*****************************************************************************/ void dumpEasyColor(FILE *fp, EasyColor *ec) { int i; fprintf(fp, "EasyColor {\n"); fprintf(fp, " char target=%s\n", ec->target); fprintf(fp, " off_t start=%d\n", (int)ec->start); fprintf(fp, " off_t end=%d\n", (int)ec->end); fprintf(fp, " off_t unit=%d\n", (int)ec->unit); fprintf(fp, " int colornum=%d\n", ec->colornum); fprintf(fp, " COLOR *colors=%p\n", ec->colors); fprintf(fp, " "); for (i = 0; i < ec->colornum; i++) { fprintf(fp, "(%d,%d,%d)[%d-%d] ", ec->colors[i].red, ec->colors[i].green, ec->colors[i].blue, ec->colors[i].start, ec->colors[i].end); } fprintf(fp, "\n"); fprintf(fp, " char url=%s\n", ec->url); fprintf(fp, " int optnum=%d\n", ec->optnum); fprintf(fp, " int optareanum=%d\n", ec->optareanum); fprintf(fp, " OPTATTR *optattrs=%p\n", ec->optattrs); fprintf(fp, "}\n"); } /*****************************************************************************/ /* 構造体EasyColorTrackの内容を表示する(デバッグ用) */ /*****************************************************************************/ void dumpEasyColorTrack(FILE *fp, EasyColorTrack *ect) { fprintf(fp, "EasyColorTrack {\n"); fprintf(fp, " ET_TYPE ettype=%d\n", ect->ettype); fprintf(fp, " char name=%s\n", ect->name); fprintf(fp, " char comment=%s\n", ect->comment); fprintf(fp, " char desc_url=%s\n", ect->desc_url); fprintf(fp, " COLOR backcolor=%d,%d,%d\n", ect->backcolor.red, ect->backcolor.green, ect->backcolor.blue); fprintf(fp, " char species=%s\n", ect->species); fprintf(fp, " char revision=%s\n", ect->revision); fprintf(fp, " char species_url=%s\n", ect->species_url); fprintf(fp, " BLEND blend=%d\n", ect->blend); fprintf(fp, " int colornum=%d\n", ect->colornum); fprintf(fp, " int colorareanum=%d\n", ect->colorareanum); fprintf(fp, " EasyColor *easycolors=%p\n", ect->easycolors); fprintf(fp, " char date=%s\n", ect->date); fprintf(fp, " char optattr=%s\n", ect->optattr); fprintf(fp, "}\n"); } /*****************************************************************************/ /* 問合せの情報を標準エラー出力に表示する */ /*****************************************************************************/ static void printColorStatus(EasyColorTrack *ect, off_t start, off_t end, off_t unit, ssize_t width, BLEND policy) { char blend_name[NAME_MAX_LEN + 1]; getBlendName(policy, blend_name, NAME_MAX_LEN + 1); fprintf(stderr, "*******************************************************************************\n"); /* fprintf(stderr, "* range=(%d,%d) %d entries (%d bytes)\n", 1, filesize/3, filesize/3, filesize); */ fprintf(stderr, "* start=%d, end=%d (num:%d), unit=%d (width=%d), blend=%s\n", (int)start, (int)end, (int)(end - start + 1), (int)unit, (int)width, blend_name); if (policy == NOBLEND && unit > 1) { fprintf(stderr, "!!!! You must set BLEND when unit is greater than 1.\n"); } fprintf(stderr, "*******************************************************************************\n"); } /*****************************************************************************/ /* color行を指定ストリームに出力する */ /*****************************************************************************/ void printEasyColor(FILE *fp, EasyColor *ec) { int i; //dumpEasyColor(stderr, ec); fprintf(fp, "color target=%s range=%d,%d unit=%d colors=", ec->target, (int)ec->start, (int)ec->end, (int)ec->unit); for (i = 0; i < ec->colornum - 1; i++) { fprintf(fp, "(%d,%d,%d),", ec->colors[i].red, ec->colors[i].green, ec->colors[i].blue); } fprintf(fp, "(%d,%d,%d)", ec->colors[i].red, ec->colors[i].green, ec->colors[i].blue); if (ec->url[0] != '\0') fprintf(fp, " url=\"%s\"\n", ec->url); else fprintf(fp, "\n"); } /*****************************************************************************/ /* colorTrack行を指定ストリームに出力する */ /*****************************************************************************/ void printEasyColorTrackHeader(FILE *fp, EasyColorTrack *ect) { fprintf(fp, "colorTrack"); fprintf(fp, " name=%s", ect->name); if (ect->comment[0] != '\0') fprintf(fp, " comment=\"%s\"", ect->comment); if (ect->desc_url[0] != '\0') fprintf(fp, " description_url=\"%s\"", ect->desc_url); fprintf(fp, " color=%d,%d,%d", ect->backcolor.red, ect->backcolor.green, ect->backcolor.blue); fprintf(fp, " species=%s", ect->species); switch (ect->blend) { case mode: fprintf(fp, " blend=mode"); break; case average: fprintf(fp, " blend=average"); break; case min: fprintf(fp, " blend=min"); break; case max: fprintf(fp, " blend=max"); break; case NOBLEND: break; default: fprintf(stderr, "*** invalid blend ***\n"); } if (ect->date) fprintf(fp, " date=%s", ect->date); fprintf(fp, "\n"); } /*****************************************************************************/ /* EasyColorTrack全体を指定ストリームに出力する */ /*****************************************************************************/ void printEasyColorTrack(FILE *fp, EasyColorTrack *ect) { int i; EasyColor *ec; if (!ect) { fprintf(fp, "EasyColorTrack is null.\n"); return; } printEasyColorTrackHeader(fp, ect); ec = ect->easycolors; for (i = 0; i < ect->colornum; i++) { printEasyColor(fp, ec); ec++; } } /*****************************************************************************/ /* EasyColor構造体の内容をヌルクリアする */ /*****************************************************************************/ void clearEasyColor(EasyColor *ec) { if (ec->colors) { free(ec->colors); onmemColors--; /* COLOR */ } if (ec->optattrs) { free(ec->optattrs); onmemOptAttrs--; /* OptAttrs */ } memset(ec, 0, sizeof(EasyColor)); } /*****************************************************************************/ /* EasyColor構造体を解放する */ /*****************************************************************************/ void destroyEasyColor(EasyColor **ec) { if (!ec) return; if (*ec) { clearEasyColor(*ec); free(*ec); onmemEColorNum--; /* EasyColor */ *ec = NULL; } } /*****************************************************************************/ /* EasyColorTrack構造体の内容をヌルクリアする */ /*****************************************************************************/ void clearEasyColorTrack(EasyColorTrack *ect) { if (!ect) return; destroyEasyColor(&ect->easycolors); memset(ect, 0, sizeof(EasyColorTrack)); } /*****************************************************************************/ /* EasyColorTrack構造体を解放する */ /*****************************************************************************/ void destroyEasyColorTrack(EasyColorTrack **ect) { if (!ect) return; if (*ect) { clearEasyColorTrack(*ect); free(*ect); onmemEColorTrackNum--; /* EasyColorTrack */ *ect = NULL; } } /*****************************************************************************/ /* 指定範囲のカラー値をブレンドして指定ストリームに出力する */ /* [戻り値] 1:成功 0:失敗 */ /*****************************************************************************/ int outputColorCache(EasyColorTrack *ect, /* EasyColroTrack構造体 */ char *outstream, /* 出力ストリーム */ off_t start, /* 開始位置(bp) */ off_t end, /* 終了位置(bp) */ int width, /* 表示ピクセル幅 */ BLEND policy) /* 合成ポリシ */ { FILE *ofp; EasyColor *ec; int unit = 0; off_t tmp; if (start > end) { tmp = start; start = end; end = tmp; } /* 表示ピクセル数を調整 */ adjustWidth(end - start + 1, &unit, &width); /* 実行時の情報を標準エラー出力へ出力 */ printColorStatus(ect, start, end, unit, width, policy); /* 出力ストリームを開く */ if (outstream == NULL || strcmp(outstream, "") == 0 || strcmp(outstream, "stdout") == 0) { ofp = stdout; } else { ofp = fopen(outstream, "w"); if (!ofp) { fprintf(stderr, "Could not open Output stream file. %s\n", outstream); return 0; } } /* EasyColorTrackのデータを指定ストリームへ出力 */ printEasyColorTrackHeader(ofp, ect); /* EasyColorは1個だけに正規化されているはずなので先頭のもののみ使う */ ec = ect->easycolors; if (!ec) { return 1; /* easycolorが0個で終了 */ } /* 合成する */ blendColor(ect, start, end, unit, width, policy); printEasyColor(ofp, ec); return 1; } /*****************************************************************************/ /* EasyColorTrack構造体にEasyColor構造体を追加する */ /* [戻り値] 成功:現在のEasyGraphの個数 失敗:0 */ /*****************************************************************************/ int addColorToTrack(EasyColorTrack *ect, EasyColor *ec) { EasyColor *easycolors; if (!ect || !ec) { fprintf(stderr, "addColorToTrack: invalid arguments.\n"); return 0; } if (ect->colornum == 0 || ect->colornum == ect->colorareanum) { ect->colorareanum += DEFAULT_COLOR_ENTRY; easycolors = (EasyColor *)calloc(ect->colorareanum, sizeof(EasyColor)); if (!easycolors) { fprintf(stderr, "addColorToTrack: memory allocation error.\n"); ect->colorareanum -= DEFAULT_COLOR_ENTRY; return 0; } onmemEColorNum++; if (ect->colorareanum > DEFAULT_COLOR_ENTRY) { memcpy(easycolors, ect->easycolors, sizeof(EasyColor) * ect->colorareanum); free(ect->easycolors); onmemEColorNum--; /* EasyColor */ } ect->easycolors = easycolors; } memcpy(&ect->easycolors[ect->colornum], ec, sizeof(EasyColor));; ect->colornum++; return ect->colornum; } /*****************************************************************************/ /* EasyColor構造体内のCOLOR情報の保持状態を正規化する */ /* (例) (1〜10,red),(11〜35,red),(36,green),(37〜40,green)などとある場合 */ /* (1〜35,red),(36〜40,green)と、情報をまとめ、等間隔のunitでない */ /* 場合は、二つのcolor行に分ける */ /*****************************************************************************/ int regularizeColor(EasyColorTrack *ect) { int ecnum; EasyColor *ec; if (!ect) { fprintf(stderr, "regularizeColor: invalid argument.\n"); return 0; } ec = ect->easycolors; return 1; }