![]() |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML LANG="ja"> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=Shift_JIS"> <TITLE>Exif ビューア</TITLE> </HEAD> <BODY BGCOLOR="#CCFFFF" onResize="resize()"> <CENTER ID="back"> <B>Exif ビューア (Firefox 3)</B> <BR> <FORM onSubmit="return false"> <DIV STYLE="margin:2px">ファイル(Exif): <INPUT TYPE=FILE ID="file" SIZE=60 onChange="read()"></DIV> <DIV ID="cont" STYLE="position:relative"> <DIV ID="img_win" STYLE="position:absolute; left:0; top:0; background-color:gray; overflow:auto"> <CANVAS ID="img" WIDTH=1 HEIGHT=1 STYLE="position:absolute; left:0; top:0; visibility:hidden"></CANVAS> </DIV> <TABLE ID="size" STYLE="position:absolute; left:0; margin-top:2px"><TR> <TD VALIGN=TOP NOWRAP>表示サイズ:</TD> <TD WIDTH=2></TD> <TD NOWRAP> <INPUT TYPE=RADIO NAME="scale" ID="fit" CHECKED onClick="scale_fit()"> 表示領域に合わせる<BR> <INPUT TYPE=RADIO NAME="scale" ID="org" onClick="scale_org()"> 原寸<BR> <INPUT TYPE=RADIO NAME="scale" ID="shr" onClick="scale_shr()"> 指定した割合で縮小 <INPUT TYPE=TEXT ID="cur_fact" READONLY VALUE="50" SIZE=5 STYLE="border:none; background-color:transparent; font-size:medium; text-align:right">% <SPAN STYLE="white-space:pre"> </SPAN><INPUT TYPE=BUTTON VALUE="← 設定" onClick="set_factor()" STYLE="padding-left:0; padding-right:0"> <INPUT TYPE=TEXT ID="fact" SIZE=5> %<BR> </TD> </TR></TABLE> <DIV ID="info_win" ALIGN=LEFT STYLE="position:absolute; top:0; background-color:white; overflow:auto"> </DIV> </DIV> </FORM> <SPAN ID="msg" STYLE="position:absolute; left:0; top:0; border-style:double; text-align:center; padding:0.8em 2em; background-color:white; border-color:#CC0000; visibility:hidden">読み込み中...</SPAN> <IFRAME ID="cvt_uc" WIDTH=1 HEIGHT=1 FRAMEBORDER=0 SCROLLING=NO STYLE="position:absolute; left:0; top:0; visibility:hidden"></IFRAME> <IFRAME ID="cvt_gpm" WIDTH=1 HEIGHT=1 FRAMEBORDER=0 SCROLLING=NO STYLE="position:absolute; left:0; top:0; visibility:hidden"></IFRAME> <IFRAME ID="cvt_gai" WIDTH=1 HEIGHT=1 FRAMEBORDER=0 SCROLLING=NO STYLE="position:absolute; left:0; top:0; visibility:hidden"></IFRAME> </CENTER> <SCRIPT LANGUAGE="JavaScript1.5" TYPE="text/javascript"> <!-- function resize() { elem_img_win.style.width = elem_img_win.style.height = elem_info_win.style.width = elem_info_win.style.height = "1px"; elem_size.style.top = elem_info_win.style.left = "0"; var img_win_width; if((img_win_width = Math.floor(document.body.scrollWidth * 0.65)) < elem_size.offsetWidth) img_win_width = elem_size.offsetWidth; var cont_height; if((cont_height = document.body.scrollHeight - elem_cont.offsetTop - elem_back.offsetTop) <= elem_size.offsetHeight) cont_height = elem_size.offsetHeight + 1; elem_img_win.style.width = String(img_win_width) + "px"; elem_img_win.style.height = elem_size.style.top = String(cont_height - elem_size.offsetHeight) + "px"; elem_info_win.style.left = String(img_win_width + 8) + "px"; var info_win_width; if((info_win_width = elem_cont.clientWidth - img_win_width - 8) < 1) info_win_width = 1; elem_info_win.style.width = String(info_win_width) + "px"; elem_info_win.style.height = String(cont_height) + "px"; if(elem_img.style.visibility == "visible") { if(elem_fit.checked) // 表示領域に合わせる scale_fit(); else adj_pos(); } } function fact_keypress(e) { if(e.which == 13) { // Enter set_factor(); return; } // 小数 キー入力チェック return (e.which < 0x20 || e.which >= 0x30 && e.which <= 0x39 || e.which == 0x2e || e.ctrlKey || e.metaKey); } function read() { // FileUpload コントロールの近くに読み込み中メッセージが表示される場合,この // タイミングでメッセージを表示すると,FileUpload コントロールの再描画でメッ // セージの表示が潰されることがあるので,FileUpload コントロールの再描画の後 // でメッセージが表示されるようにタイミングを調整する. setTimeout(read2, 0); } function read2() { elem_img.style.visibility = "hidden"; elem_img.width = elem_img.height = 1; elem_img.style.left = elem_img.style.top = "0"; elem_img.style.width = elem_img.style.height = ""; elem_info_win.innerHTML = ""; with(elem_msg) { style.left = String(document.body.scrollLeft + ((document.body.clientWidth - offsetWidth ) >> 1)) + "px"; style.top = String(document.body.scrollTop + ((document.body.clientHeight - offsetHeight) >> 1)) + "px"; style.visibility = "visible"; } document.documentElement.style.cursor = "wait"; elem_info_win.style.overflow = "hidden"; // スクロール バーに前のスクロール量が残ってしまうので,おまじない. setTimeout(read3, 0); } function read3() { elem_info_win.style.overflow = "auto"; // スクロール バーに前のスクロール量が残ってしまうので,おまじない. // Firefox 7 では nsIDOMFile オブジェクトの getAsBinary(),getAsDataURL() 等が削除された. // 代わりに,Firefox 3.6 で新設された FileReader オブジェクトを使って同様のことができるので, // FileReader オブジェクトが使えればそれを使い,使えなければ以前のままの処理とするように修正 // した. if(typeof FileReader == "function") { file_reader = new FileReader(); file_reader.onload = read_fr; file_reader.readAsBinaryString(elem_file.files.item(0)); } else { file = elem_file.files.item(0).getAsBinary(); read4(); } } function read_fr() { file = file_reader.result; file_reader = undefined; read4(); } function read4() { if((file.length < 2) ? true : ((get_short_be(file, 0) == 0xffd8/*SOI*/) ? read_JPEG() : read_TIFF())) { with(elem_msg) { style.visibility = "hidden"; style.left = style.top = "0"; } document.documentElement.style.cursor = "auto"; alert("ファイルが Exif 形式でないか、このプログラムでは対応していないバージョンのファイルです。"); return; } put_info(); // 情報表示 } // 縮小割合設定 function set_factor() { var fact = elem_fact.value; if(fact.search(/\S/) == -1) // 未入力 return; if(fact.search(/^\s*\d*\.?\d*\s*$/) == -1) { fact = 0; } else { if(isNaN(fact = parseFloat(fact))) fact = 0; else fact = Math.round(fact * 100) / 100; } if(fact == 0 || fact > 100) { alert("縮小割合の入力に誤りがあります。"); return; } factor = fact / 100; elem_cur_fact.value = String(fact); if(elem_shr.checked) scale_shr(); } // 表示領域に合わせる function scale_fit() { if(elem_img.width / elem_img_win.clientWidth > elem_img.height / elem_img_win.clientHeight) { elem_img.style.width = (elem_img.width > elem_img_win.clientWidth) ? "100%" : ""; elem_img.style.height = ""; } else { elem_img.style.width = ""; elem_img.style.height = (elem_img.height > elem_img_win.clientHeight) ? "100%" : ""; } adj_pos(); } // 原寸 function scale_org() { elem_img.style.width = elem_img.style.height = ""; adj_pos(); } // 指定した割合で縮小 function scale_shr() { elem_img.style.width = Math.round(elem_img.width * factor); elem_img.style.height = ""; adj_pos(); } // 画像位置調整 function adj_pos() { // 一旦位置をゼロにして,スクロール バーの有無を確定する. elem_img.style.left = elem_img.style.top = "0"; // 画像の幅/高さが表示領域より小さければセンタリング if(elem_img.offsetWidth < elem_img_win.clientWidth) elem_img.style.left = String((elem_img_win.clientWidth - elem_img.offsetWidth) >> 1) + "px"; if(elem_img.offsetHeight < elem_img_win.clientHeight) elem_img.style.top = String((elem_img_win.clientHeight - elem_img.offsetHeight) >> 1) + "px"; } // **** JPEG **** function read_JPEG() { TIFF_tags[I_Exif_IFD].value = undefined; var Y = undefined; var X; for(var off = 2; ; ) { var len; if(off + 2 > file.length) return -1; switch(get_short_be(file, off)) { // marker case 0xffda: // SOS if(TIFF_tags[I_Exif_IFD].value == undefined) return -1; if(Y == undefined) return -1; img_width = X; img_height = Y; // JPEG のレンダリングはブラウザに任せる elem_src = document.createElement("IMG"); elem_src.width = X; elem_src.height = Y; elem_src.onload = JPEG_loaded; // Firefox 7 では nsIDOMFile オブジェクトの getAsBinary(),getAsDataURL() 等が削除された. // 代わりに,Firefox 3.6 で新設された FileReader オブジェクトを使って同様のことができるので, // FileReader オブジェクトが使えればそれを使い,使えなければ以前のままの処理とするように修正 // した. if(typeof FileReader == "function") { file_reader = new FileReader(); file_reader.onload = read_JPEG_fr; file_reader.readAsDataURL(elem_file.files.item(0)); } else { elem_src.src = elem_file.files.item(0).getAsDataURL(); } return 0; case 0xffe1: // APP1 if(off + 4 > file.length) return -1; len = get_short_be(file, off + 2); if(off + 2 + len > file.length) return -1; if(len >= 8) { if(file.substr(off + 4, 6) == "Exif\0\0") { if(read_Exif(file.substr(off + 10, len - 8))) return -1; } } break; case 0xffc0: // SOF0 if(off + 4 > file.length) return -1; len = get_short_be(file, off + 2); if(off + 2 + len > file.length) return -1; if(len < 8) return -1; if(len != 8 + get_byte(file, off + 9) * 3) return -1; if(get_byte(file, off + 4) != 8) return -1; Y = get_short_be(file, off + 5); X = get_short_be(file, off + 7); break; } if(off + 4 > file.length) return -1; off += 2 + get_short_be(file, off + 2); } } function read_JPEG_fr() { elem_src.src = file_reader.result; file_reader = undefined; } function JPEG_loaded() { show_img(); // 画像表示 document.documentElement.style.cursor = "auto"; } // **** TIFF **** function read_TIFF() { if(read_Exif(file)) return -1; // チェック switch(img_width = TIFF_tags[I_ImageWidth].value) { case undefined: case 0: return -1; } switch(img_height = TIFF_tags[I_ImageLength].value) { case undefined: case 0: return -1; } value = TIFF_tags[I_BitsPerSample].value; if(value[0] != 8 || value[1] != 8 || value[2] != 8) return -1; if(TIFF_tags[I_Compression].value != 1) // no compression 以外 return -1; if(TIFF_tags[I_SamplesPerPixel].value != 3) return -1; switch(RowsPerStrip = TIFF_tags[I_RowsPerStrip].value) { case undefined: // Exif の仕様ではデフォルトなし case 0: return -1; } if((StripOffsets = TIFF_tags[I_StripOffsets].value) == undefined) return -1; if((StripByteCounts = TIFF_tags[I_StripByteCounts].value) == undefined) return -1; if(StripOffsets.length != StripByteCounts.length) return -1; var pc_chunky; switch(TIFF_tags[I_PlanarConfiguration].value) { case 1: // Chunky pc_chunky = true; if(StripOffsets.length != ((RowsPerStrip < img_height) ? Math.floor((img_height + RowsPerStrip - 1) / RowsPerStrip) : 1)) return -1; break; case 2: // Planar pc_chunky = false; if(StripOffsets.length != ((RowsPerStrip < img_height) ? 3 * Math.floor((img_height + RowsPerStrip - 1) / RowsPerStrip) : 3)) return -1; break; default: return -1; } var pi_RGB; var strip_bytes; var ss_422; var i; switch(TIFF_tags[I_PhotometricInterpretation].value) { case 2: // RGB pi_RGB = true; if(pc_chunky) { // Chunky row_bytes = img_width * 3; strip_bytes = RowsPerStrip * row_bytes; for(i = 0; i < StripOffsets.length - 1; i++) { if(StripByteCounts[i] != strip_bytes) return -1; } if(StripByteCounts[i] != (img_height - (StripOffsets.length - 1) * RowsPerStrip) * row_bytes) return -1; } else { // Planar if(StripOffsets.length % 3) return -1; row_bytes = img_width; strip_bytes = RowsPerStrip * row_bytes; var strips1 = StripOffsets.length / 3; for(i = 0; i < StripOffsets.length; i++) { if(StripByteCounts[i] != (((i + 1) % strips1) ? strip_bytes : (img_height - (strips1 - 1) * RowsPerStrip) * row_bytes)) return -1; } } break; case 6: // YCbCr pi_RGB = false; if(!pc_chunky) // Chunky 以外 return -1; if((value = TIFF_tags[I_YCbCrSubSampling].value) == undefined) return -1; if(value[0] != 2 || value[1] != 1 && value[1] != 2) // 4:2:2,4:2:0 以外 return -1; if(!(ss_422 = (value[1] == 1))) { // 4:2:0 if(RowsPerStrip < img_height) { if(RowsPerStrip % 2) // RowsPerStrip が奇数 return -1; } } switch(TIFF_tags[I_YCbCrPositioning].value) { case 1: // centered cosited = false; break; case 2: // cosited cosited = true; break; default: return -1; } value = TIFF_tags[I_YCbCrCoefficients].value; if(!value[0].d || !value[1].d || !value[2].d) return -1; LR = value[0].n / value[0].d; LG = value[1].n / value[1].d; LB = value[2].n / value[2].d; width_odd = img_width % 2; if(ss_422) { // 4:2:2 row_bytes = (img_width + width_odd) * 2; strip_bytes = RowsPerStrip * row_bytes; for(i = 0; i < StripOffsets.length - 1; i++) { if(StripByteCounts[i] != strip_bytes) return -1; } if(StripByteCounts[i] != (img_height - (StripOffsets.length - 1) * RowsPerStrip) * row_bytes) return -1; } else { // 4:2:0 row_bytes = (img_width + width_odd) * 3; // 2 行分 strip_bytes = RowsPerStrip / 2 * row_bytes; for(i = 0; i < StripOffsets.length - 1; i++) { if(StripByteCounts[i] != strip_bytes) return -1; } if(StripByteCounts[i] != (img_height - (StripOffsets.length - 1) * RowsPerStrip + img_height % 2) / 2 * row_bytes) return -1; } break; default: return -1; } if((value = TIFF_tags[I_ReferenceBlackWhite].value) == undefined) { // JEITA CP-3451A の仕様ではこうなっているが,YCbCr のときのデフォルト値は // [0, 255, 128, 255, 128, 255] でなくていいのか? RB0 = RB1 = RB2 = 0; SC0 = 1; SC1 = SC2 = (pi_RGB) ? 1 : 127 / 128; } else { if(!value[0].d || !value[1].d || !value[2].d || !value[3].d || !value[4].d || !value[5].d) return -1; RB0 = value[0].n / value[0].d; RB1 = value[2].n / value[2].d; RB2 = value[4].n / value[4].d; SC0 = 255 / (value[1].n / value[1].d - RB0); var CR = (pi_RGB) ? 255 : 127; SC1 = CR / (value[3].n / value[3].d - RB1); SC2 = CR / (value[5].n / value[5].d - RB2); } // 画像 elem_src = document.createElement("CANVAS"); elem_src.width = img_width; elem_src.height = img_height; src_ctx = elem_src.getContext("2d"); src_ctx.fillStyle = "rgba(0,0,0,1)"; src_ctx.fillRect(0, 0, img_width, img_height); src_img = src_ctx.getImageData(0, 0, img_width, img_height); img_data = src_img.data; i_strip = -1; if(pi_RGB) { // RGB if(pc_chunky) { // Chunky img_rows = img_height; strip_rows = 0; i_img = 0; setTimeout(TIFF_RGB_Chunky, 0); } else { // Planar plane = -1; img_rows = 0; setTimeout(TIFF_RGB_Planar, 0); } } else { // YCbCr SC1_L = SC1 * (2 - 2 * LB); SC2_L = SC2 * (2 - 2 * LR); img_rows = img_height; strip_rows = 0; i_img = 0; if(ss_422) { // 4:2:2 setTimeout(TIFF_YCbCr_422, 0); } else { // 4:2:0 img_stride = img_width * 4; sub_width = (img_width + width_odd) / 2; prev_Y0 = new Array(); prev_Y1 = new Array(); prev_Cb_L = new Array(); prev_Cr_L = new Array(); prev_Y0.length = prev_Y1.length = prev_Cb_L.length = prev_Cr_L.length = sub_width; setTimeout(TIFF_YCbCr_420, 0); } } return 0; } function TIFF_RGB_Chunky() { for(var cnt = 100; cnt; cnt--) { if(!strip_rows) { strip_off = StripOffsets[++i_strip]; strip_rows = RowsPerStrip; } for(var off_end = strip_off + row_bytes; strip_off < off_end; strip_off += 3) { var w; w = Math.round((file.charCodeAt(strip_off ) - RB0) * SC0); // R img_data[i_img ] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((file.charCodeAt(strip_off + 1) - RB1) * SC1); // G img_data[i_img + 1] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((file.charCodeAt(strip_off + 2) - RB2) * SC2); // B img_data[i_img + 2] = (w < 0) ? 0 : ((w > 255) ? 255 : w); i_img += 4; } if(!--img_rows) { TIFF_ready(); return; } strip_rows--; } setTimeout(TIFF_RGB_Chunky, 0); } function TIFF_RGB_Planar() { for(var cnt = 100; cnt; cnt--) { if(!img_rows) { if(plane == 2) { TIFF_ready(); return; } switch(++plane) { case 0: RB = RB0; SC = SC0; break; case 1: RB = RB1; SC = SC1; break; default: RB = RB2; SC = SC2; } i_img = plane; img_rows = img_height; strip_rows = 0; } if(!strip_rows) { strip_off = StripOffsets[++i_strip]; strip_rows = RowsPerStrip; } for(var off_end = strip_off + row_bytes; strip_off < off_end; strip_off++) { var w = Math.round((file.charCodeAt(strip_off) - RB) * SC); img_data[i_img] = (w < 0) ? 0 : ((w > 255) ? 255 : w); i_img += 4; } img_rows--; strip_rows--; } setTimeout(TIFF_RGB_Planar, 0); } function TIFF_YCbCr_422() { for(var cnt = 100; cnt; cnt--) { if(!strip_rows) { strip_off = StripOffsets[++i_strip]; strip_rows = RowsPerStrip; } for(var off_end = strip_off + row_bytes; ; ) { var Cb_L = (file.charCodeAt(strip_off + 2) - RB1) * SC1_L; var Cr_L = (file.charCodeAt(strip_off + 3) - RB2) * SC2_L; var Y; var R, B; var w; Y = (file.charCodeAt(strip_off) - RB0) * SC0; w = Math.round(R = Cr_L + Y); // R img_data[i_img ] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L + Y); // B img_data[i_img + 2] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img + 1] = (w < 0) ? 0 : ((w > 255) ? 255 : w); if((strip_off += 4) == off_end && width_odd) { // 幅が奇数のときの最終カラム i_img += 4; break; } Y = (file.charCodeAt(strip_off - 3) - RB0) * SC0; if(cosited) { if(strip_off < off_end) { // 最終カラム以外 Cb_L = (Cb_L + (file.charCodeAt(strip_off + 2) - RB1) * SC1_L) / 2; Cr_L = (Cr_L + (file.charCodeAt(strip_off + 3) - RB2) * SC2_L) / 2; } } w = Math.round(R = Cr_L + Y); // R img_data[i_img + 4] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L + Y); // B img_data[i_img + 6] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img + 5] = (w < 0) ? 0 : ((w > 255) ? 255 : w); i_img += 8; if(strip_off == off_end) // 最終カラム break; } if(!--img_rows) { TIFF_ready(); return; } strip_rows--; } setTimeout(TIFF_YCbCr_422, 0); } function TIFF_YCbCr_420() { for(var cnt = 50; cnt; cnt--) { if(!strip_rows) { strip_off = StripOffsets[++i_strip]; strip_rows = RowsPerStrip; } var i_prev = 0; for(off_end = strip_off + row_bytes; ; ) { var Cb_L = (file.charCodeAt(strip_off + 4) - RB1) * SC1_L; var Cr_L = (file.charCodeAt(strip_off + 5) - RB2) * SC2_L; var Cb_L_p, Cr_L_p; var i_img2; var Cb_L_2, Cr_L_2; var Y; var R, B; var w; if(img_rows < img_height) { Cb_L_p = prev_Cb_L[i_prev]; Cr_L_p = prev_Cr_L[i_prev]; i_img2 = i_img - img_stride; if(cosited) { Cb_L_2 = (Cb_L_p + Cb_L) / 2; Cr_L_2 = (Cr_L_p + Cr_L) / 2; } else { Cb_L_2 = Cb_L_p; Cr_L_2 = Cr_L_p; } Y = prev_Y0[i_prev]; w = Math.round(R = Cr_L_2 + Y); // R img_data[i_img2 ] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L_2 + Y); // B img_data[i_img2 + 2] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img2 + 1] = (w < 0) ? 0 : ((w > 255) ? 255 : w); } Y = (file.charCodeAt(strip_off) - RB0) * SC0; w = Math.round(R = Cr_L + Y); // R img_data[i_img ] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L + Y); // B img_data[i_img + 2] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img + 1] = (w < 0) ? 0 : ((w > 255) ? 255 : w); if(img_rows != 1) { // 高さが奇数のときの最終行以外 prev_Cb_L[i_prev] = Cb_L; prev_Cr_L[i_prev] = Cr_L; prev_Y0[i_prev] = (file.charCodeAt(strip_off + 2) - RB0) * SC0; } if((strip_off += 6) == off_end && width_odd) { // 幅が奇数のときの最終カラム i_img += 4; break; } var Cb_L_n; var Cr_L_n; var Cb_L_3 = Cb_L; var Cr_L_3 = Cr_L; if(cosited) { if(strip_off < off_end) { // 最終カラム以外 Cb_L_n = (file.charCodeAt(strip_off + 4) - RB1) * SC1_L; Cr_L_n = (file.charCodeAt(strip_off + 5) - RB2) * SC2_L; Cb_L_3 = (Cb_L + Cb_L_n) / 2; Cr_L_3 = (Cr_L + Cr_L_n) / 2; } } if(img_rows < img_height) { // 最初の行以外 if(cosited) { if(strip_off == off_end) { // 最終カラム Cb_L_2 = (Cb_L_p + Cb_L) / 2; Cr_L_2 = (Cr_L_p + Cr_L) / 2; } else { Cb_L_2 = (Cb_L_p + prev_Cb_L[i_prev + 1] + Cb_L + Cb_L_n) / 4; Cr_L_2 = (Cr_L_p + prev_Cr_L[i_prev + 1] + Cr_L + Cr_L_n) / 4; } } else { Cb_L_2 = Cb_L_p; Cr_L_2 = Cr_L_p; } Y = prev_Y1[i_prev]; w = Math.round(R = Cr_L_2 + Y); // R img_data[i_img2 + 4] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L_2 + Y); // B img_data[i_img2 + 6] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img2 + 5] = (w < 0) ? 0 : ((w > 255) ? 255 : w); } Y = (file.charCodeAt(strip_off - 5) - RB0) * SC0; w = Math.round(R = Cr_L_3 + Y); // R img_data[i_img + 4] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L_3 + Y); // B img_data[i_img + 6] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img + 5] = (w < 0) ? 0 : ((w > 255) ? 255 : w); if(img_rows != 1) // 高さが奇数のときの最終行以外 prev_Y1[i_prev] = (file.charCodeAt(strip_off - 3) - RB0) * SC0; i_img += 8; if(strip_off == off_end) // 最終カラム break; i_prev++; } i_img += img_stride; if((img_rows -= 2) <= 0) { if(!img_rows) { // 高さが偶数 for(i_prev = 0; i_prev < sub_width; i_prev++) { Cb_L = prev_Cb_L[i_prev]; Cr_L = prev_Cr_L[i_prev]; Y = prev_Y0[i_prev]; w = Math.round(R = Cr_L + Y); // R img_data[i_img ] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L + Y); // B img_data[i_img + 2] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img + 1] = (w < 0) ? 0 : ((w > 255) ? 255 : w); if(i == sub_width - 1 && width_odd) // 幅が奇数のときの最終カラム break; Y = prev_Y1[i_prev]; if(cosited) { if(i < sub_width - 1) { // 最終カラム以外 Cb_L = (Cb_L + prev_Cb_L[i_prev + 1]) / 2; Cr_L = (Cr_L + prev_Cr_L[i_prev + 1]) / 2; } } w = Math.round(R = Cr_L + Y); // R img_data[i_img + 4] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round(B = Cb_L + Y); // B img_data[i_img + 6] = (w < 0) ? 0 : ((w > 255) ? 255 : w); w = Math.round((Y - LB * B - LR * R) / LG); // G img_data[i_img + 5] = (w < 0) ? 0 : ((w > 255) ? 255 : w); i_img += 8; } } prev_Y0 = prev_Y1 = prev_Cb_L = prev_Cr_L = undefined; TIFF_ready(); return; } strip_rows -= 2; } setTimeout(TIFF_YCbCr_420, 0); } function TIFF_ready() { src_ctx.putImageData(src_img, 0, 0); src_ctx = undefined; src_img = undefined; show_img(); // 画像表示 document.documentElement.style.cursor = "auto"; } // Exif 情報読み込み function read_Exif(tiff) { // Image File Header if(tiff.length < 8) return -1; switch(get_short_be(tiff, 0)) { case 0x4949: // II get_value[SHORT] = get_short = get_short_le; get_value[LONG] = get_long = get_long_le; get_slong = get_slong_le; break; case 0x4d4d: // MM get_value[SHORT] = get_short = get_short_be; get_value[LONG] = get_long = get_long_be; get_slong = get_slong_be; break; default: return -1; } if(get_short(tiff, 2) != 42) return -1; var value; // 0th IFD if(read_IFD(tiff, get_long(tiff, 4), TIFF_tags)) return -1; // チェック if(TIFF_tags[I_Exif_IFD].value == undefined) return -1; // 解像度 value = TIFF_tags[I_XResolution].value; if(!value.d) return -1; resolution = value.n / value.d; value = TIFF_tags[I_YResolution].value; if(!value.d) return -1; if(resolution != value.n / value.d) return -1; // 画像方向 Orientation = TIFF_tags[I_Orientation].value; if(!Orientation || Orientation > 8) return -1; // Exif IFD if(read_IFD(tiff, TIFF_tags[I_Exif_IFD].value, Exif_tags)) return -1; // チェック // 被写体領域 if((value = Exif_tags[I_SubjectArea].value) != undefined) { if(value.length < 2 || value.length > 4) return -1; } // GPS IFD if(TIFF_tags[I_GPS_IFD].value != undefined) { if(read_IFD(tiff, TIFF_tags[I_GPS_IFD].value, GPS_tags)) return -1; } return 0; } // IFD 読み込み function read_IFD(tiff, off, tags) { if(!off || off + 2 > tiff.length) return -1; var n_dir = get_short(tiff, off); off += 2; if(off + n_dir * 12 + 4 > tiff.length) return -1; var i; // 初期値(undefined or デフォルト値) for(i = 0; i < tags.length; i++) tags[i].value = tags[i][3]; for(; n_dir; n_dir--, off += 12) { var tag = get_short(tiff, off); // Tag for(var i_tag = 0; i_tag < tags.length; i_tag++) { if(tags[i_tag][0] == tag) { // Type var type = get_short(tiff, off + 2); if(tags[i_tag][1] == SHORT_LONG) { // SHORT or LONG switch(type) { case SHORT: case LONG: break; default: return -1; } } else { if(type != tags[i_tag][1]) return -1; } // Count var count = get_long(tiff, off + 4); if(tags[i_tag][2]) { if(count != tags[i_tag][2]) return -1; } // Value or Offset var val_off = off + 8; if(count * field_size[type] > 4) { val_off = get_long(tiff, val_off); if(val_off + count * field_size[type] > tiff.length) return -1; } switch(type) { case ASCII: case UNDEFINED: tags[i_tag].value = tiff.substr(val_off, count); break; default: if(tags[i_tag][2] == 1) { // Count tags[i_tag].value = get_value[type](tiff, val_off); } else { tags[i_tag].value = new Array(); tags[i_tag].value.length = count; for(i = 0; i < count; i++) { tags[i_tag].value[i] = get_value[type](tiff, val_off); val_off += field_size[type]; } } } break; } } } return 0; } // 画像表示 function show_img() { var ctx = elem_img.getContext("2d"); if(Orientation < 5) { elem_img.width = img_width; elem_img.height = img_height; var m11 = 1, m22 = 1; switch(Orientation) { case 2: // 上右 m11 = -1; break; case 3: // 下右 m11 = m22 = -1; break; case 4: // 下左 m22 = -1; break; } ctx.setTransform(m11, 0, 0, m22, (m11 < 0) ? img_width : 0, (m22 < 0) ? img_height : 0); } else { elem_img.width = img_height; elem_img.height = img_width; var m12 = 1, m21 = 1; switch(Orientation) { case 6: // 右上 m21 = -1; break; case 7: // 右下 m12 = m21 = -1; break; case 8: // 左下 m12 = -1; break; } ctx.setTransform(0, m12, m21, 0, (m21 < 0) ? img_height : 0, (m12 < 0) ? img_width : 0); } ctx.drawImage(elem_src, 0, 0); elem_src = undefined; if (elem_fit.checked) // 表示領域に合わせる scale_fit(); else if(elem_org.checked) // 原寸 scale_org(); else // 指定した割合で縮小 scale_shr(); elem_img.style.visibility = "visible"; with(elem_msg) { style.visibility = "hidden"; style.left = style.top = "0"; } } // 情報表示 function put_info() { var value, value2; var unit; var str, str2; var n, m; var off; var uc_src = undefined; var gpm_src = undefined; var gai_src = undefined; var rtn; var i; info = "<TABLE CELLSPACING=0 STYLE='white-space:pre; margin:0; padding:4px 0'>"; // 画像の幅/高さ info_item("サイズ", String(img_width) + " x " + String(img_height)); // 解像度 unit = ResolutionUnit_str[TIFF_tags[I_ResolutionUnit].value]; info_item("解像度", (unit == undefined) ? "不明" : String(resolution) + " " + unit); // 作成日時 if((value = TIFF_tags[I_DateTime].value) != undefined) info_item("作成日時", DateTime(value, Exif_tags[I_SubsecTime].value)); // タイトル if((value = TIFF_tags[I_ImageDescription].value) != undefined) info_item("タイトル", ascii(value)); // メーカー if((value = TIFF_tags[I_Make].value) != undefined) info_item("メーカー", ascii(value)); // モデル if((value = TIFF_tags[I_Model].value) != undefined) info_item("モデル", ascii(value)); // ソフトウェア if((value = TIFF_tags[I_Software].value) != undefined) info_item("使用ソフトウェア", ascii(value)); // アーティスト if((value = TIFF_tags[I_Artist].value) != undefined) info_item("作者", ascii(value)); // 撮影著作権者/編集著作権者 if((value = TIFF_tags[I_Copyright].value) != undefined) { str = ""; str2 = ""; if((i = value.indexOf("\0")) != -1) { if((str = value.substr(0, i)) == " ") str = ""; var i2; if((i2 = value.indexOf("\0", i + 1)) != -1) str2 = value.substr(i + 1, i2 - i - 1); } if(str.length) info_item("撮影著作権者", info_text(str)); if(str2.length) info_item("編集著作権者", info_text(str2)); } info_item("<BR>", ""); // 色空間情報 if((value = Exif_tags[I_ColorSpace].value) != undefined) { str = ColorSpace_str[value]; info_item("色空間情報", (str == undefined) ? "不明" : str); } // 再生ガンマ if((value = Exif_tags[I_Gamma].value) != undefined) info_item("再生ガンマ", rational(value, 3, undefined)); // メーカー ノート if((value = Exif_tags[I_MakerNote].value) != undefined) info_item("メーカー ノート", "(" + String(value.length) + " バイト)"); // ユーザ コメント if((value = Exif_tags[I_UserComment].value) != undefined) { rtn = conv_text(value, "info_uc"); info_item("ユーザ コメント", rtn.txt); if(rtn.src != undefined) { elem_cvt_uc.onload = uc_loaded; uc_src = rtn.src; } } // 関連音声ファイル if((value = Exif_tags[I_RelatedSoundFile].value) != undefined) info_item("関連音声ファイル", ascii(value)); // 原画像データの生成日時 if((value = Exif_tags[I_DateTimeOriginal].value) != undefined) info_item("原画像データ生成日時", DateTime(value, Exif_tags[I_SubsecTimeOriginal].value)); // ディジタル データの作成日時 if((value = Exif_tags[I_DateTimeDigitized].value) != undefined) info_item("ディジタル データ作成日時", DateTime(value, Exif_tags[I_SubsecTimeDigitized].value)); // 露出時間 if((value = Exif_tags[I_ExposureTime].value) != undefined) info_item("露出時間", (value.d) ? ((value.n == 1) ? "1/" + String(value.d) : rational(value, 6, undefined)) + " 秒" : "不明"); // Fナンバー if((value = Exif_tags[I_FNumber].value) != undefined) info_item("F値", rational(value, 1, undefined)); // 露出プログラム value = Exif_tags[I_ExposureProgram].value; info_item("露出プログラム", ((value > 8) ? "不明" : ExposureProgram_str[value])); // スペクトル感度 if((value = Exif_tags[I_SpectralSensitivity].value) != undefined) info_item("スペクトル感度", ascii(value)); // ISO スピード レート if((value = Exif_tags[I_ISOSpeedRatings].value) != undefined) { str = ""; for(i = 0; i < value.length; i++) { if(i) str += ", "; str += String(value[i]); } info_item("ISO スピード レート", str); } // 光電変換関数 if((value = Exif_tags[I_OECF].value) != undefined) { if(value.length < 4) { str = "不明"; } else { n = get_short(value, 0); m = get_short(value, 2); off = 4; str = "<TABLE CELLSPACING=0 CELLPADDING=0 STYLE='white-space:pre'><TR>"; for(i = n; i; i--) { if((value2 = get_asciiz(value, off)) == undefined) break; str += "<TD STYLE='padding-right:1em'>" + info_text(value2) + "</TD>"; off += value2.length + 1; } if(i) { str = "不明"; } else { if(off + n * m * 8 == value.length) { str += "</TR>"; for(; m; m--) { str += "<TR>"; for(i = n; i; i--) { str += "<TD STYLE='padding-right:1em'>" + rational(get_srational(value, off), 3, undefined) + "</TD>"; off += 8; } str += "</TR>"; } str += "</TABLE>"; } else { str = "不明"; } } } info_item("光電変換関数", str); } // シャッター スピード if((value = Exif_tags[I_ShutterSpeedValue].value) != undefined) info_item("シャッター スピード", rational(value, 3, "APEX")); // 絞り値 if((value = Exif_tags[I_ApertureValue].value) != undefined) info_item("絞り値", rational(value, 3, "APEX")); // 輝度値 if((value = Exif_tags[I_BrightnessValue].value) != undefined) info_item("輝度値", (value.n == -1/*FFFFFFFF.H*/) ? "不明" : rational(value, 3, "APEX")); // 露光補正値 if((value = Exif_tags[I_ExposureBiasValue].value) != undefined) info_item("露出補正値", rational(value, 3, "APEX")); // レンズ最小F値 if((value = Exif_tags[I_MaxApertureValue].value) != undefined) info_item("レンズ最小F値", rational(value, 3, "APEX")); // 被写体距離 if((value = Exif_tags[I_SubjectDistance].value) != undefined) { switch(value.n) { case 0: str = "不明"; break; case 4294967295: // FFFFFFFF.H str = "∞"; break; default: str = rational(value, 3, "m"); } info_item("被写体距離", str); } // 測光方式 info_item("測光方式", ((str = MeteringMode_str[Exif_tags[I_MeteringMode].value]) == undefined) ? "不明" : str); // 光源 info_item("光源", ((str = LightSource_str[Exif_tags[I_LightSource].value]) == undefined) ? "不明" : str); // フラッシュ if((value = Exif_tags[I_Flash].value) != undefined) { str = ((value & 0x01) ? "ストロボ発光" : "ストロボ発光せず") + "<BR>"; switch(value & 0x06) { case 0x00: str += "ストロボのリターン検出機能なし"; break; case 0x04: str += "ストロボのリターン検出されず"; break; case 0x06: str += "ストロボのリターン検出"; break; default: str += "ストロボのリターン状態不明"; } str += "<BR>"; switch(value & 0x18) { case 0x08: str += "強制発光モード"; break; case 0x10: str += "強制非発光モード"; break; case 0x18: str += "自動発光モード"; break; default: str += "ストロボ モード不明"; } str += "<BR>"; str += ((value & 0x20) ? "ストロボ機能なし" : "ストロボ機能あり") + "<BR>"; str += (value & 0x40) ? "赤目軽減あり" : "赤目軽減なし、または赤目モード不明"; info_item("フラッシュ", str); } // レンズ焦点距離 if((value = Exif_tags[I_FocalLength].value) != undefined) info_item("レンズ焦点距離", rational(value, 1, "mm")); // 被写体領域 if((value = Exif_tags[I_SubjectArea].value) != undefined) { str = "X: " + String(value[0]) + ", Y: " + String(value[1]); switch(value.length) { case 3: str += ", 直径: " + String(value[2]); break; case 4: str += ", 幅: " + String(value[2]) + ", 高さ: " + String(value[3]); break; } info_item("被写体領域", str); } // フラッシュ強度 if((value = Exif_tags[I_FlashEnergy].value) != undefined) info_item("フラッシュ強度", rational(value, 1, "BCPS")); // 空間周波数応答 if((value = Exif_tags[I_SpatialFrequencyResponse].value) != undefined) { if(value.length < 4) { str = "不明"; } else { n = get_short(value, 0); m = get_short(value, 2); off = 4; str = "<TABLE CELLSPACING=0 CELLPADDING=0 STYLE='white-space:pre'><TR>"; for(i = n; i; i--) { if((value2 = get_asciiz(value, off)) == undefined) break; str += "<TD STYLE='padding-right:1em'>" + info_text(value2) + "</TD>"; off += value2.length + 1; } if(i) { str = "不明"; } else { if(off + n * m * 8 == value.length) { str += "</TR>"; for(; m; m--) { str += "<TR>"; for(i = n; i; i--) { str += "<TD STYLE='padding-right:1em'>" + rational(get_rational(value, off), 3, undefined) + "</TD>"; off += 8; } str += "</TR>"; } str += "</TABLE>"; } else { str = "不明"; } } } info_item("空間周波数応答", str); } // 焦点面解像度単位 unit = ResolutionUnit_str[Exif_tags[I_FocalPlaneResolutionUnit].value]; // 焦点面の幅の解像度 if((value = Exif_tags[I_FocalPlaneXResolution].value) != undefined) info_item("焦点面の幅の解像度", (unit == undefined) ? "不明" : rational(value, 1, unit)); // 焦点面の高さの解像度 if((value = Exif_tags[I_FocalPlaneYResolution].value) != undefined) info_item("焦点面の高さの解像度", (unit == undefined) ? "不明" : rational(value, 1, unit)); // 被写体位置 if((value = Exif_tags[I_SubjectLocation].value) != undefined) info_item("被写体位置", "X: " + String(value[0]) + ", Y: " + String(value[1])); // 露出インデックス if((value = Exif_tags[I_ExposureIndex].value) != undefined) info_item("露出インデックス", rational(value, 1, undefined)); // センサ方式 if((value = Exif_tags[I_SensingMethod].value) != undefined) info_item("センサ方式", ((str = SensingMethod_str[value]) == undefined) ? "不明" : str); // ファイル ソース info_item("ファイル ソース", ((value = Exif_tags[I_FileSource].value.charCodeAt()) > 3) ? "不明" : FileSource_str[value]); // シーン タイプ info_item("シーン タイプ", (Exif_tags[I_SceneType].value.charCodeAt() == 1) ? "直接撮影された画像" : "不明"); // CFA パターン if((value = Exif_tags[I_CFAPattern].value) != undefined) { if(value.length < 4) { str = "不明"; } else { n = get_short(value, 0); m = get_short(value, 2); if(4 + n * m == value.length) { off = 4; str = "<TABLE CELLSPACING=0 CELLPADDING=0 STYLE='white-space:pre'>"; for(; m; m--) { str += "<TR>"; for(i = n; i; i--) { value2 = get_byte(value, off); str += "<TD STYLE='padding-right:1em'>" + ((value2 > 6) ? "不明" : CFA_str[value2]) + "</TD>"; off++; } str += "</TR>"; } str += "</TABLE>"; } else { str = "不明"; } } info_item("CFA パターン", str); } // 個別画像処理 info_item("個別画像処理", ((value = Exif_tags[I_CustomRendered].value) > 1) ? "不明" : CustomRendered_str[value]); // 露出モード if((value = Exif_tags[I_ExposureMode].value) != undefined) info_item("露出モード", (value > 2) ? "不明" : ExposureMode_str[value]); // ホワイト バランス if((value = Exif_tags[I_WhiteBalance].value) != undefined) info_item("ホワイト バランス", (value > 1) ? "不明" : WhiteBalance_str[value]); // ディジタル ズーム倍率 if((value = Exif_tags[I_DigitalZoomRatio].value) != undefined) info_item("ディジタル ズーム倍率", (value.n) ? rational(value, 1, undefined) : "ディジタル ズーム未使用"); // 35mm 換算レンズ焦点距離 if((value = Exif_tags[I_FocalLengthIn35mmFilm].value) != undefined) info_item("35mm 換算レンズ焦点距離", (value) ? String(value) + " mm" : "不明"); // 撮影シーン タイプ info_item("撮影シーン タイプ", ((value = Exif_tags[I_SceneCaptureType].value) > 3) ? "不明" : SceneCaptureType_str[value]); // ゲイン制御 if((value = Exif_tags[I_GainControl].value) != undefined) info_item("ゲイン制御", (value > 4) ? "不明" : GainControl_str[value]); // 撮影コントラスト info_item("撮影コントラスト", ((value = Exif_tags[I_Contrast].value) > 2) ? "不明" : Contrast_str[value]); // 撮影彩度 info_item("撮影彩度", ((value = Exif_tags[I_Saturation].value) > 2) ? "不明" : Saturation_str[value]); // 撮影シャープネス info_item("撮影シャープネス", ((value = Exif_tags[I_Sharpness].value) > 2) ? "不明" : Sharpness_str[value]); // 撮影条件記述情報 if((value = Exif_tags[I_DeviceSettingDescription].value) != undefined) { if(value.length < 4) { str = ""; } else { n = get_short(value, 0); m = get_short(value, 2); off = 4; str = "<TABLE CELLSPACING=0 CELLPADDING=0 STYLE='white-space:pre'>"; for(; m; m--) { str += "<TR>"; for(i = n; i; i--) { if(off + 2 > value.length) break; // JEITA CP-3451A の仕様では Signature を含むことになっているが,Signature のバイト オーダーが // TIFF ヘッダのバイト オーダーと違ったら,Signature のバイト オーダーに従うのだろうか? var get_short_w; switch(get_short_be(value, off)) { case 0xfeff: // big endian get_short_w = get_short_be; off += 2; break; case 0xfffe: // little endian get_short_w = get_short_le; off += 2; break; default: // Signature が無いときは TIFF ヘッダのバイト オーダーに従う get_short_w = get_short; } str2 = ""; for(; ; ) { if(off + 2 > value.length) { value2 = true; break; } value2 = get_short_w(value, off); off += 2; if(!value2) break; str2 += String.fromCharCode(value2); } if(value2) break; str += "<TD STYLE='padding-right:1em'>" + info_text(str2) + "</TD>"; } if(i) break; str += "</TR>"; } if(m) str = ""; else str += "</TABLE>"; } info_item("撮影条件記述情報", str); } // 被写体距離レンジ if((value = Exif_tags[I_SubjectDistanceRange].value) != undefined) info_item("被写体距離レンジ", ((str = SubjectDistanceRange_str[value]) == undefined) ? "不明" : str); // 画像ユニーク ID if((value = Exif_tags[I_ImageUniqueID].value) != undefined) info_item("画像ユニーク ID", ascii(value)); // GPS if(TIFF_tags[I_GPS_IFD].value != undefined) { info_item("<BR>", ""); // 緯度,経度 str = ""; if((value = GPS_tags[I_GPSLatitudeRef].value) != undefined && (value2 = GPS_tags[I_GPSLatitude].value) != undefined) { unit = LatitudeRef_str[ascii(value)]; if(unit != undefined && value2[0].d && value2[1].d && value2[2].d) { str = unit + " " + String(value2[0].n / value2[0].d) + "度"; if(value2[0].d == 1) { str += String(value2[1].n / value2[1].d) + "分"; if(value2[1].d == 1) str += String(value2[2].n / value2[2].d) + "秒"; } } else { str = "緯度不明"; } } if((value = GPS_tags[I_GPSLongitudeRef].value) != undefined && (value2 = GPS_tags[I_GPSLongitude].value) != undefined) { if(str.length) str += "<BR>"; unit = LongitudeRef_str[ascii(value)]; if(unit != undefined && value2[0].d && value2[1].d && value2[2].d) { str += unit + " " + String(value2[0].n / value2[0].d) + "度"; if(value2[0].d == 1) { str += String(value2[1].n / value2[1].d) + "分"; if(value2[1].d == 1) str += String(value2[2].n / value2[2].d) + "秒"; } } else { str += "経度不明"; } } if(str.length) info_item("経緯度", str); // 高度 if((value = GPS_tags[I_GPSAltitude].value) != undefined) { switch(GPS_tags[I_GPSAltitudeRef].value) { case 0: str = ""; break; case 1: str = "-"; break; default: str = undefined; } info_item("高度", (str == undefined || !value.d) ? "不明" : str + rational(value, 1, "m")); } // GPS 時間(原子時計の時間) if((value = GPS_tags[I_GPSTimeStamp].value) != undefined) { if(!value[0].d || !value[1].d || !value[2].d) { str = "不明"; } else { str = String(value[0].n / value[0].d) + "時"; if(value[0].d == 1) { str += String(value[1].n / value[1].d) + "分"; if(value[1].d == 1) str += String(value[2].n / value[2].d) + "秒"; } str += " UTC"; } info_item("GPS 時間", str); } // 測位に使った衛星信号 if((value = GPS_tags[I_GPSSatellites].value) != undefined) info_item("測位に用いた衛星信号", ascii(value)); // GPS 受信機の状態 if((value = GPS_tags[I_GPSStatus].value) != undefined) { str = GPSStatus_str[ascii(value)]; info_item("GPS 受信機の状態", (str == undefined) ? "不明" : str); } // GPS の測位方法 if((value = GPS_tags[I_GPSMeasureMode].value) != undefined) { str = GPSMeasureMode_str[ascii(value)]; info_item("GPS の測位方法", (str == undefined) ? "不明" : str); } // 測位の信頼性 if((value = GPS_tags[I_GPSDOP].value) != undefined) info_item("測位の信頼性", rational(value, 1, undefined)); // 速度 if((value = GPS_tags[I_GPSSpeed].value) != undefined) { unit = GPSSpeedRef_str[ascii(GPS_tags[I_GPSSpeedRef].value)]; info_item("速度", (unit == undefined) ? "不明" : rational(value, 1, unit)); } // 進行方向 if((value = GPS_tags[I_GPSTrack].value) != undefined) { unit = DirectionRef_str[ascii(GPS_tags[I_GPSTrackRef].value)]; info_item("進行方向", (unit == undefined || !value.d) ? "不明" : unit + " " + (value.n / value.d).toFixed(2) + " 度"); } // 撮影した画像の方向 if((value = GPS_tags[I_GPSImgDirection].value) != undefined) { unit = DirectionRef_str[ascii(GPS_tags[I_GPSImgDirectionRef].value)]; info_item("撮影した画像の方向", (unit == undefined || !value.d) ? "不明" : unit + " " + (value.n / value.d).toFixed(2) + " 度"); } // 測位に用いた地図データ if((value = GPS_tags[I_GPSMapDatum].value) != undefined) info_item("測地系", ascii(value)); // 目的地の緯度,目的地の経度 str = ""; if((value = GPS_tags[I_GPSDestLatitudeRef].value) != undefined && (value2 = GPS_tags[I_GPSDestLatitude].value) != undefined) { unit = LatitudeRef_str[ascii(value)]; if(unit != undefined && value2[0].d && value2[1].d && value2[2].d) { str = unit + " " + String(value2[0].n / value2[0].d) + "度"; if(value2[0].d == 1) { str += String(value2[1].n / value2[1].d) + "分"; if(value2[1].d == 1) str += String(value2[2].n / value2[2].d) + "秒"; } } else { str = "緯度不明"; } } if((value = GPS_tags[I_GPSDestLongitudeRef].value) != undefined && (value2 = GPS_tags[I_GPSDestLongitude].value) != undefined) { if(str.length) str += "<BR>"; unit = LongitudeRef_str[ascii(value)]; if(unit != undefined && value2[0].d && value2[1].d && value2[2].d) { str += unit + " " + String(value2[0].n / value2[0].d) + "度"; if(value2[0].d == 1) { str += String(value2[1].n / value2[1].d) + "分"; if(value2[1].d == 1) str += String(value2[2].n / value2[2].d) + "秒"; } } else { str += "経度不明"; } } if(str.length) info_item("目的地の経緯度", str); // 目的地の方角 if((value = GPS_tags[I_GPSDestBearing].value) != undefined) { unit = DirectionRef_str[ascii(GPS_tags[I_GPSDestBearingRef].value)]; info_item("目的地の方角", (unit == undefined || !value.d) ? "不明" : unit + " " + (value.n / value.d).toFixed(2) + " 度"); } // 目的地までの距離 if((value = GPS_tags[I_GPSDestDistance].value) != undefined) { unit = GPSDestDistanceRef_str[ascii(GPS_tags[I_GPSDestDistanceRef].value)]; info_item("目的地までの距離", (unit == undefined) ? "不明" : rational(value, 1, unit)); } // 測位方式の名称 if((value = GPS_tags[I_GPSProcessingMethod].value) != undefined) { rtn = conv_text(value, "info_gpm"); info_item("測位方式", rtn.txt); if(rtn.src != undefined) { elem_cvt_gpm.onload = gpm_loaded; gpm_src = rtn.src; } } // 測位地点の名称 if((value = GPS_tags[I_GPSAreaInformation].value) != undefined) { rtn = conv_text(value, "info_gai"); info_item("測位地点", rtn.txt); if(rtn.src != undefined) { elem_cvt_gai.onload = gai_loaded; gai_src = rtn.src; } } // GPS 日付 if((value = GPS_tags[I_GPSDateStamp].value) != undefined) { var dt = value.match(/(\d{4}):(\d{2}):(\d{2})/); if(dt == null) { str = "不明"; } else { if(dt[2].charAt(0) == "0") dt[2] = dt[2].substr(1); if(dt[3].charAt(0) == "0") dt[3] = dt[3].substr(1); str = dt[1] + "年" + dt[2] + "月" + dt[3] + "日 UTC"; } info_item("GPS 日付", str); } // GPS 補正測位 if((value = GPS_tags[I_GPSDifferential].value) != undefined) info_item("GPS 補正測位", (value > 1) ? "不明" : GPSDifferential_str[value]); } info += "</TABLE>"; elem_info_win.innerHTML = info; if(uc_src != undefined) elem_cvt_uc.src = uc_src; if(gpm_src != undefined) elem_cvt_gpm.src = gpm_src; if(gai_src != undefined) elem_cvt_gai.src = gai_src; } function info_item(nam, val) { info += "<TR><TD VALIGN=TOP STYLE='padding:0 4px'>" + nam + "</TD><TD VALIGN=TOP STYLE='padding:0 4px'>" + val + "</TD></TR>"; } function ascii(value) { var len = value.indexOf("\0"); return info_text((len == -1) ? value : value.substr(0, len)); } function rational(value, digits, unit) { if(value.d) { var str = (value.n / value.d).toFixed(digits); for(var i = str.length - 1; str[i] != "."; i--) { if(str[i] != "0") { i++; break; } } str = str.substr(0, i); if(unit != undefined) str += " " + unit; return str; } return "不明"; } function DateTime(value_dt, value_sub) { var dt = value_dt.match(/(\d{4}):(\d{2}):(\d{2}) (\d{2}):(\d{2}):(\d{2})/); if(dt == null) return "不明"; if(dt[2].charAt(0) == "0") dt[2] = dt[2].substr(1); if(dt[3].charAt(0) == "0") dt[3] = dt[3].substr(1); if(dt[4].charAt(0) == "0") dt[4] = dt[4].substr(1); if(dt[5].charAt(0) == "0") dt[5] = dt[5].substr(1); if(dt[6].charAt(0) == "0") dt[6] = dt[6].substr(1); var str = dt[1] + "年" + dt[2] + "月" + dt[3] + "日 " + dt[4] + "時" + dt[5] + "分" + dt[6]; if(value_sub != undefined) { var sub; if((sub = ascii(value_sub)).length) str += "." + sub; } return str + "秒"; } // コード変換 function conv_text(value, id) { if(value.length < 8) return {txt:""}; var str; var i; switch(value.substr(0, 8)) { case "ASCII\0\0\0": // ASCII return {txt:info_text(value.substr(8))}; case "JIS\0\0\0\0\0": // JIS // JEITA CP-3451A の仕様では「JIS X0208-1990」としか書かれていない. // JIS X 0201 のラテン文字集合等と組み合わせて使うのか等,詳細は不明. // ここでは単純に,ISO-2022-JP エンコーディングであるものとして扱うことにする. str = ""; for(i = 8; i < value.length; i++) str += "%" + ("0" + value.charCodeAt(i).toString(16)).substr(-2); return {txt:"<SPAN ID='" + id + "'></SPAN>", src:"data:text/plain;charset=ISO-2022-JP," + str}; case "UNICODE\0": // Unicode str = ""; for(i = 8; i + 1 < value.length; i += 2) str += String.fromCharCode(get_short(value, i)); return {txt:info_text(str)}; case "\0\0\0\0\0\0\0\0": // Undefined // PC に依存.ここではシフト JIS と仮定. str = ""; for(i = 8; i < value.length; i++) str += "%" + ("0" + value.charCodeAt(i).toString(16)).substr(-2); return {txt:"<SPAN ID='" + id + "'></SPAN>", src:"data:text/plain;charset=Shift_JIS," + str}; } return {txt:""}; } function uc_loaded() { document.getElementById("info_uc").innerHTML = info_text(this.contentDocument.body.textContent); }; function gpm_loaded() { document.getElementById("info_gpm").innerHTML = info_text(this.contentDocument.body.textContent); }; function gai_loaded() { document.getElementById("info_gai").innerHTML = info_text(this.contentDocument.body.textContent); }; function info_text(text) { elem_esc.textContent = text.replace(/[\x01-\x1f]/g, " ").replace(/ *$/, ""); return elem_esc.innerHTML; } // BYTE 取得 function get_byte(data, off) { return data.charCodeAt(off); } // SHORT 取得 var get_short; // big endian の SHORT 取得 function get_short_be(data, off) { return (data.charCodeAt(off) << 8) | data.charCodeAt(off + 1); } // little endian の SHORT 取得 function get_short_le(data, off) { return (data.charCodeAt(off + 1) << 8) | data.charCodeAt(off); } // LONG 取得 var get_long; // big endian の LONG 取得 function get_long_be(data, off) { return data.charCodeAt(off) * 0x1000000 + ((data.charCodeAt(off + 1) << 16) | (data.charCodeAt(off + 2) << 8) | data.charCodeAt(off + 3)); } // little endian の LONG 取得 function get_long_le(data, off) { return data.charCodeAt(off + 3) * 0x1000000 + ((data.charCodeAt(off + 2) << 16) | (data.charCodeAt(off + 1) << 8) | data.charCodeAt(off)); } // SLONG 取得 var get_slong; // big endian の SLONG 取得 function get_slong_be(data, off) { return (data.charCodeAt(off) << 24) | (data.charCodeAt(off + 1) << 16) | (data.charCodeAt(off + 2) << 8) | data.charCodeAt(off + 3); } // little endian の SLONG 取得 function get_slong_le(data, off) { return (data.charCodeAt(off + 3) << 24) | (data.charCodeAt(off + 2) << 16) | (data.charCodeAt(off + 1) << 8) | data.charCodeAt(off); } // RATIONAL 取得 function get_rational(data, off) { return {n:get_long(data, off), d:get_long(data, off + 4)}; } // SRATIONAL 取得 function get_srational(data, off) { return {n:get_slong(data, off), d:get_slong(data, off + 4)}; } // null 終端 ASCII 文字列取得 function get_asciiz(data, off) { var str = ""; for(; ; ) { var c; if((c = data.charAt(off)) == "\0") return str; str += c; if(++off == data.length) return undefined; } } //---------------------------------------------------------- // TIFF field types BYTE = 1; ASCII = 2; SHORT = 3; LONG = 4; RATIONAL = 5; //SBYTE = 6; UNDEFINED = 7; //SSHORT = 8; //SLONG = 9; SRATIONAL = 10; //FLOAT = 11; //DOUBLE = 12; SHORT_LONG = 0x10000; // SHORT or LONG field_size = [0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8]; // 値取得関数テーブル get_value = [ undefined, get_byte, undefined, undefined, // get_short(endian 確定後に設定) undefined, // get_long (endian 確定後に設定) get_rational, undefined, undefined, undefined, undefined, get_srational, undefined, undefined ]; // TIFF Rev.6.0 IFD TIFF_tags = [ // Tag Type Count デフォルト // A. 画像データの構成に関するタグ [ 256, SHORT_LONG, 1 ], // ImageWidth [ 257, SHORT_LONG, 1 ], // ImageLength [ 258, SHORT, 3, [8, 8, 8] ], // BitsPerSample [ 259, SHORT, 1 ], // Compression [ 262, SHORT, 1 ], // PhotometricInterpretation [ 274, SHORT, 1, 1 ], // Orientation [ 277, SHORT, 1, 3 ], // SamplesPerPixel [ 284, SHORT, 1, 1 ], // PlanarConfiguration [ 530, SHORT, 2 ], // YCbCrSubSampling [ 531, SHORT, 1, 1 ], // YCbCrPositioning [ 282, RATIONAL, 1, {n:72, d:1} ], // XResolution [ 283, RATIONAL, 1, {n:72, d:1} ], // YResolution [ 296, SHORT, 1, 2 ], // ResolutionUnit // B. 画像の記録位置に関するタグ [ 273, SHORT_LONG, 0 ], // StripOffsets [ 278, SHORT_LONG, 1 ], // RowsPerStrip [ 279, SHORT_LONG, 0 ], // StripByteCounts // JPEGInterchangeFormat // JPEGInterchangeFormatLength // C. 画像データの特性に関するタグ [ 301, SHORT, 768 ], // TransferFunction Count: 3 * 256 [ 318, RATIONAL, 2 ], // WhitePoint [ 319, RATIONAL, 6 ], // PrimaryChromaticities [ 529, RATIONAL, 3, [{n:299, d:1000}, {n:587, d:1000}, {n:114, d:1000}]], // YCbCrCoefficients [ 532, RATIONAL, 6 ], // ReferenceBlackWhite // D. その他のタグ [ 306, ASCII, 20 ], // DateTime [ 270, ASCII, 0 ], // ImageDescription [ 271, ASCII, 0 ], // Make [ 272, ASCII, 0 ], // Model [ 305, ASCII, 0 ], // Software [ 315, ASCII, 0 ], // Artist [33432, ASCII, 0 ], // Copyright // Exif プライベート タグ [34665, LONG, 1 ], // Exif IFD [34853, LONG, 1 ] // GPS IFD ]; I_ImageWidth = 0; I_ImageLength = 1; I_BitsPerSample = 2; I_Compression = 3; I_PhotometricInterpretation = 4; I_Orientation = 5; I_SamplesPerPixel = 6; I_PlanarConfiguration = 7; I_YCbCrSubSampling = 8; I_YCbCrPositioning = 9; I_XResolution = 10; I_YResolution = 11; I_ResolutionUnit = 12; I_StripOffsets = 13; I_RowsPerStrip = 14; I_StripByteCounts = 15; I_YCbCrCoefficients = 19; I_ReferenceBlackWhite = 20; I_DateTime = 21; I_ImageDescription = 22; I_Make = 23; I_Model = 24; I_Software = 25; I_Artist = 26 I_Copyright = 27; I_Exif_IFD = 28; I_GPS_IFD = 29; // Exif IFD Exif_tags = [ // Tag Type Count デフォルト // A. バージョンに関するタグ [36864, UNDEFINED, 4, "0221"], // Exif バージョン [40960, UNDEFINED, 4, "0100"], // 対応フラッシュピックス バージョン // B. 画像データの特性に関するタグ [40961, SHORT, 1 ], // 色空間情報 [42240, RATIONAL, 1 ], // 再生ガンマ // C. 構造に関するタグ [37121, UNDEFINED, 4 ], // 各コンポーネントの意味 [37122, RATIONAL, 1 ], // 画像圧縮モード [40962, SHORT_LONG, 1 ], // 実効画像幅 [40963, SHORT_LONG, 1 ], // 実効画像高さ // D. ユーザ情報に関するタグ [37500, UNDEFINED, 0 ], // メーカ ノート [37510, UNDEFINED, 0 ], // ユーザ コメント // E. 関連ファイル情報に関するタグ [40964, ASCII, 13 ], // 関連音声ファイル // F. 日時に関するタグ [36867, ASCII, 20 ], // 原画像データの生成日時 [36868, ASCII, 20 ], // ディジタル データの作成日時 [37520, ASCII, 0 ], // DateTime のサブセック [37521, ASCII, 0 ], // DateTimeOriginal のサブセック [37522, ASCII, 0 ], // DateTimeDigitized のサブセック // G. 撮影条件に関するタグ [33434, RATIONAL, 1 ], // 露出時間 [33437, RATIONAL, 1 ], // Fナンバー [34850, SHORT, 1, 0 ], // 露出プログラム [34852, ASCII, 0 ], // スペクトル感度 [34855, SHORT, 0 ], // ISO スピード レート [34856, UNDEFINED, 0 ], // 光電変換関数 [37377, SRATIONAL, 1 ], // シャッター スピード [37378, RATIONAL, 1 ], // 絞り値 [37379, SRATIONAL, 1 ], // 輝度値 [37380, SRATIONAL, 1 ], // 露光補正値 [37381, RATIONAL, 1 ], // レンズ最小F値 [37382, RATIONAL, 1 ], // 被写体距離 [37383, SHORT, 1, 0 ], // 測光方式 [37384, SHORT, 1, 0 ], // 光源 [37385, SHORT, 1 ], // フラッシュ [37386, RATIONAL, 1 ], // レンズ焦点距離 [37396, SHORT, 0 ], // 被写体領域 Count: 2 〜 4 [41483, RATIONAL, 1 ], // フラッシュ強度 [41484, UNDEFINED, 0 ], // 空間周波数応答 [41486, RATIONAL, 1 ], // 焦点面の幅の解像度 [41487, RATIONAL, 1 ], // 焦点面の高さの解像度 [41488, SHORT, 1, 2 ], // 焦点面解像度単位 [41492, SHORT, 2 ], // 被写体位置 [41493, RATIONAL, 1 ], // 露出インデックス [41495, SHORT, 1 ], // センサ方式 [41728, UNDEFINED, 1, "\x03"], // ファイル ソース [41729, UNDEFINED, 1, "\x01"], // シーン タイプ [41730, UNDEFINED, 0 ], // CFA パターン [41985, SHORT, 1, 0 ], // 個別画像処理 [41986, SHORT, 1 ], // 露出モード [41987, SHORT, 1 ], // ホワイト バランス [41988, RATIONAL, 1 ], // ディジタル ズーム倍率 [41989, SHORT, 1 ], // 35mm 換算レンズ焦点距離 [41990, SHORT, 1, 0 ], // 撮影シーン タイプ [41991, SHORT, 1 ], // ゲイン制御 [41992, SHORT, 1, 0 ], // 撮影コントラスト [41993, SHORT, 1, 0 ], // 撮影彩度 [41994, SHORT, 1, 0 ], // 撮影シャープネス [41995, UNDEFINED, 0 ], // 撮影条件記述情報 [41996, SHORT, 1 ], // 被写体距離レンジ // H. その他のタグ [42016, ASCII, 33 ] // 画像ユニーク ID ]; I_ColorSpace = 2; I_Gamma = 3; I_MakerNote = 8; I_UserComment = 9; I_RelatedSoundFile = 10; I_DateTimeOriginal = 11; I_DateTimeDigitized = 12; I_SubsecTime = 13; I_SubsecTimeOriginal = 14; I_SubsecTimeDigitized = 15; I_ExposureTime = 16; I_FNumber = 17; I_ExposureProgram = 18; I_SpectralSensitivity = 19; I_ISOSpeedRatings = 20; I_OECF = 21; I_ShutterSpeedValue = 22; I_ApertureValue = 23; I_BrightnessValue = 24; I_ExposureBiasValue = 25; I_MaxApertureValue = 26; I_SubjectDistance = 27; I_MeteringMode = 28; I_LightSource = 29; I_Flash = 30; I_FocalLength = 31; I_SubjectArea = 32; I_FlashEnergy = 33; I_SpatialFrequencyResponse = 34; I_FocalPlaneXResolution = 35; I_FocalPlaneYResolution = 36; I_FocalPlaneResolutionUnit = 37; I_SubjectLocation = 38; I_ExposureIndex = 39; I_SensingMethod = 40; I_FileSource = 41; I_SceneType = 42; I_CFAPattern = 43; I_CustomRendered = 44; I_ExposureMode = 45; I_WhiteBalance = 46; I_DigitalZoomRatio = 47; I_FocalLengthIn35mmFilm = 48; I_SceneCaptureType = 49; I_GainControl = 50; I_Contrast = 51; I_Saturation = 52; I_Sharpness = 53; I_DeviceSettingDescription = 54; I_SubjectDistanceRange = 55; I_ImageUniqueID = 56; // GPS IFD GPS_tags = [ // Tag Type Count デフォルト // A. GPS に関するタグ [ 0, BYTE, 4, [2, 2, 0, 0]], // GPS タグのバージョン [ 1, ASCII, 2 ], // 北緯(N) or 南緯(S) [ 2, RATIONAL, 3 ], // 緯度(数値) [ 3, ASCII, 2 ], // 東経(E) or 西経(W) [ 4, RATIONAL, 3 ], // 経度(数値) [ 5, BYTE, 1, 0 ], // 高度の基準 [ 6, RATIONAL, 1 ], // 高度(数値) [ 7, RATIONAL, 3 ], // GPS 時間(原子時計の時間) [ 8, ASCII, 0 ], // 測位に使った衛星信号 [ 9, ASCII, 2 ], // GPS 受信機の状態 [10, ASCII, 2 ], // GPS の測位方法 [11, RATIONAL, 1 ], // 測位の信頼性 [12, ASCII, 2, "K" ], // 速度の単位 [13, RATIONAL, 1 ], // 速度(数値) [14, ASCII, 2, "T" ], // 進行方向の単位 [15, RATIONAL, 1 ], // 進行方向(数値) [16, ASCII, 2, "T" ], // 撮影した画像の方向の単位 [17, RATIONAL, 1 ], // 撮影した画像の方向(数値) [18, ASCII, 0 ], // 測位に用いた地図データ [19, ASCII, 2 ], // 目的地の北緯(N) or 南緯(S) [20, RATIONAL, 3 ], // 目的地の緯度(数値) [21, ASCII, 2 ], // 目的地の東経(E) or 西経(W) [22, RATIONAL, 3 ], // 目的地の経度(数値) [23, ASCII, 2, "T" ], // 目的地の方角の単位 [24, RATIONAL, 1 ], // 目的の方角(数値) [25, ASCII, 2, "K" ], // 目的地までの距離の単位 [26, RATIONAL, 1 ], // 目的地までの距離(数値) [27, UNDEFINED, 0 ], // 測位方式の名称 [28, UNDEFINED, 0 ], // 測位地点の名称 [29, ASCII, 11 ], // GPS 日付 [30, SHORT, 1 ] // GPS 補正測位 ]; I_GPSLatitudeRef = 1; I_GPSLatitude = 2; I_GPSLongitudeRef = 3; I_GPSLongitude = 4; I_GPSAltitudeRef = 5; I_GPSAltitude = 6; I_GPSTimeStamp = 7; I_GPSSatellites = 8; I_GPSStatus = 9; I_GPSMeasureMode = 10; I_GPSDOP = 11; I_GPSSpeedRef = 12; I_GPSSpeed = 13; I_GPSTrackRef = 14; I_GPSTrack = 15; I_GPSImgDirectionRef = 16; I_GPSImgDirection = 17; I_GPSMapDatum = 18; I_GPSDestLatitudeRef = 19; I_GPSDestLatitude = 20; I_GPSDestLongitudeRef = 21; I_GPSDestLongitude = 22; I_GPSDestBearingRef = 23; I_GPSDestBearing = 24; I_GPSDestDistanceRef = 25; I_GPSDestDistance = 26; I_GPSProcessingMethod = 27; I_GPSAreaInformation = 28; I_GPSDateStamp = 29; I_GPSDifferential = 30; ResolutionUnit_str = []; ResolutionUnit_str[2] = "DPI"; ResolutionUnit_str[3] = "ドット/cm"; ColorSpace_str = {1:"sRGB", 0xffff:"Uncalibrated"}; ExposureProgram_str = ["", "マニュアル", "通常プログラム", "絞り優先", "シャッター優先", "creative プログラム", "action プログラム", "人物モード", "風景モード"]; MeteringMode_str = [undefined, "平均", "中央重点", "スポット", "マルチ スポット", "分割測光", "部分測光"]; MeteringMode_str[255] = "その他"; LightSource_str = []; LightSource_str[1] = "昼光"; LightSource_str[2] = "蛍光灯"; LightSource_str[3] = "タングステン"; LightSource_str[4] = "フラッシュ"; LightSource_str[9] = "晴天"; LightSource_str[10] = "曇天"; LightSource_str[11] = "日陰"; LightSource_str[12] = "昼光色蛍光灯"; LightSource_str[13] = "昼白色蛍光灯"; LightSource_str[14] = "白色蛍光灯"; LightSource_str[15] = "温白色蛍光灯"; LightSource_str[17] = "標準光 A"; LightSource_str[18] = "標準光 B"; LightSource_str[19] = "標準光 C"; LightSource_str[20] = "D55"; LightSource_str[21] = "D65"; LightSource_str[22] = "D75"; LightSource_str[23] = "D50"; LightSource_str[24] = "ISO studio tungsten"; LightSource_str[255] = "その他"; SensingMethod_str = [undefined, "", "単板カラー センサ", "2 板カラー センサ", "3 板カラー センサ", "色順次カラー センサ", undefined, "3 線リニア センサ", "色順次リニア センサ"]; FileSource_str = ["その他", "透過型スキャナ", "反射型スキャナ", "DSC"]; CFA_str = ["RED", "GREEN", "BLUE", "CYAN", "MAGENTA", "YELLOW", "WHITE"]; CustomRendered_str = ["通常処理", "特殊処理"]; ExposureMode_str = ["自動", "マニュアル", "オート ブラケット"]; WhiteBalance_str = ["自動", "マニュアル"]; SceneCaptureType_str = ["標準", "風景", "人物", "夜景"]; GainControl_str = ["なし", "弱い増感", "強い増感", "弱い減感", "強い減感"]; Contrast_str = ["標準", "軟調", "硬調"]; Saturation_str = ["標準", "低彩度", "高彩度"]; Sharpness_str = ["標準", "弱い", "強い"]; SubjectDistanceRange_str = [undefined, "マクロ", "近景", "遠景"]; LatitudeRef_str = {"N":"北緯", "S":"南緯"}; LongitudeRef_str = {"E":"東経", "W":"西経"}; GPSStatus_str = {"A":"測位中", "V":"未測位(中断中)"}; GPSMeasureMode_str = {"2":"2 次元測位中", "3":"3 次元測位中"}; GPSSpeedRef_str = {"K":"km/h", "M":"mi/h", "N":"ノット"}; DirectionRef_str = {"T":"真方位", "M":"磁気方位"}; GPSDestDistanceRef_str = {"K":"km", "M":"mi", "N":"海里"}; GPSDifferential_str = ["単独測位", "Differential 補正測位"]; elem_back = document.getElementById("back"); elem_file = document.getElementById("file"); elem_cont = document.getElementById("cont"); elem_img_win = document.getElementById("img_win"); elem_img = document.getElementById("img"); elem_size = document.getElementById("size"); elem_fit = document.getElementById("fit"); elem_org = document.getElementById("org"); elem_shr = document.getElementById("shr"); elem_cur_fact = document.getElementById("cur_fact"); elem_fact = document.getElementById("fact"); elem_info_win = document.getElementById("info_win"); elem_msg = document.getElementById("msg"); elem_cvt_uc = document.getElementById("cvt_uc"); elem_cvt_gpm = document.getElementById("cvt_gpm"); elem_cvt_gai = document.getElementById("cvt_gai"); elem_esc = document.createElement("SPAN"); factor = 0.5; // 縮小割合 初期値 50% resize(); elem_fact.onkeypress = fact_keypress; document.forms[0].reset(); // ページを再ロードしたときのため //--> </SCRIPT> </BODY> </HTML> |