2014-11-06

太古坊的「真我」Retake


2009年那時相機的Miniature Fake效果(或稱Tilt-shift Fake)還未普及,我是將用傻瓜機拍的相片用電腦Gimp軟件加工來做散景,以滿足未有大光圈鏡頭拍不到淺景深相片的心願,其中一輯是在太古坊的拍的「真我」(連結)。

早前終於在二手市場買了支CCTV鏡頭,是Fujian 35mm F/1.7,散景效果不錯,今天再經過太古坊,便用它再拍一次比較比較。







2014-10-20

Living Fearlessly


我兒時沒有如很多的小朋友一樣「怕黑」,但很早便知自己有點畏高。隨著年紀長大,了解到畏高是非理性的,明白扶手欄杆不會無端端斷下來,明白外牆玻璃不會無端端碎裂,以致自己會突然由高處墜下。但是,只要視覺知道自己身在高處,心便會寒起來,腳便會抖震。我努力希望可解決畏高的恐懼,心理上,嘗試閉上眼幻想自己從高處墜下的感覺,現實上,亦玩過一次海洋公園的跳樓機。(真是很驚!)但現在我只可以說我的畏高只是被我的理性壓抑著,只是不會影響到我的生活罷了,但我仍是不敢玩笨豬跳。

我另一缺憾是不能看恐怖故事(小說,電視劇,電影等),只要是情節有故事引線凝聚小小恐怖氣氛,我便接受不了。其實,我理性上,我知道我只要跨過那個所謂恐怖情節,就算是後來有甚麼血甚麼嘔心的,其實已經沒事了。所以我了解到我的驚恐源於對未來不確定的東西。

事實上,這種感覺真是影響到我的日常生活,我是一個容易緊張的人,容易手心,前額,腋下大量出汗。

較早時,由於心翳不舒服,心跳很快,加上我有膽固醇高的病歷,醫生安排了我做一連串的測試:靜態心電圖,運動心電圖,心臟超聲波,心臟電腦掃描,也找不到問題。其實我有懷疑過是否自己壓力太大,但是那段時間工作不忙,沒有很多壓力,家庭也沒有特別問題。

我以前常同人笑說:恐懼(驚)的最高境界就是不知道驚甚麼。所以我想,如果我想克服恐懼,首先要承認自己恐懼,另外,要知道自己恐懼甚麼。

近來,由於買了本書:鍾灼輝的《我死過,所以知道怎麼活:與死神相遇的11分鐘》,順便在互聯網看其他人講Near Death Experience(NDE/瀕死經驗),看過Anita Moorjani的分享,最令我感受深的,就是她提倡的living fearlessly(連結)。人生或許最恐懼的就是死亡,但是一個有瀕死經驗的人告訴我們可無懼地生活,那是多麼的震撼哩!

2014-10-19

靜坐鬧鐘 Bodhi Timer


我在屋企是有靜坐的習慣,我自己是用電子表來計時的,但坦白講,它的電子響鬧是不太適合靜坐用的。在外面禪修,導師常用引磬來提示時間的,它的聲響和餘音是很適合在安靜的環境下作出提示。

近期溫暖人間(第395期)有介紹用智能手機App "Insight Timer Meditation Timer" 來做禪修鬧鐘(連結),其實我先前也曾有這想法,但始終缺乏安全感,覺得如果驚App失效會使靜坐時心緒不寧。

儘管上網看看,評語又Okay喎,但我一向不喜歡App需要太多的權限,我發覺Insight Timer Meditation Timer要求的權限太多,如:

  • 應用程式內購買
  • 尋找裝置上的帳戶
  • 接收網際網路資料
  • 修改系統設定
  • 完整網路存取權

加上它很"大食",要成10M記憶,(我一向奉行簡約主義,其實是我手機很低檔!)所以我再在Google Play找找其他類似的程式。

真是琳瑯滿目,但我其實只是要找一個Timer罷了!

終於發現一個叫 "Bodhi Timer" 的App (連結),它乎合我的要求,需要的記憶只是1.8M,而且沒有其他如上網的權限,加上是開源,亦加上一份信心。

不過,最重要重要還是程式要穩定,我見它的Timer engine is 用另一開源程式 Ralph Gootee TeaTimer。而響鬧就用Android內建的通知系統,故可不需要將電話Keep Awake(亦可省電)

現在用了幾次,非常滿意,我很喜歡它的引磬聲效,而且它容許將音量調教成百分比(如圖),故可將電話響鬧音量保留而將修禪響鬧音量收細。


現在,只是發現一小小bug,是在測試聲響時如按下停止,以後便不能再發聲,要害我做一次Force Stop,不過這也不是大問題,我會繼續使用它來靜坐鬧鐘 。

P.S. 在靜坐時,我一定會將電話定為飛行模式(連Wifi也關閉),因我不想有電磁波干擾。

2014-08-14

英文諺語mdx版


我多年前買了一本英文諺語書,希望可寫英文時可多用一點諺語以增加可讀性,但我遇到兩個困難:(1) 如何隨時在幾千個諺語選出合適的諺語?(2) 很多時在腦海想出的是中文成語,很難做好中英對照。

現在智能手機很普及,我也用字典 app 隨時查閱生字,而中英雙向也很方便。(我用的是 mdict。忽發奇想,可否將英文諺語做成字典格式?

在網上找找資料,mdict 用的字典格式是 mdx,而且也有 mdx 生成器(字典製作工具),所以我首先做一迷你版以作proof-of-concept,證實可行。然後在網上搜羅大量英文諺語(及其中文翻譯),便開始便校對,de-duplication 和關鍵詞 indexing,結果我做了 3341 則英文諺語。


 安裝方法(以Android為例 )

(1) 自在這裡下載mdx檔案。

(2) 通常檔案會被送在/sdcard/download,但如果字典app是mdict,便要將它搬到/sdcard/mdict/doc

(3) 由於很多關鍵詞都可指向多過一條條目,所以記緊要turn on "multi-dictionary mode"



(4) 如輸入英文,字典便可搜索出關鍵詞出現的數目(如conscience有12條)



(5) 選取關鍵詞便列出其下的諺語(英中對照)



(6) 你亦可單用中文輸入,例如單入「一」字便列出以下條目:



希望大家覺得有用!


2014-06-30

高清機頂盒轉換記3之《終於放棄8仔》


自從在2011年將8仔的電源組件換了新之後,機身溫度問題解決了(見高清機頂盒轉換記2之《回歸8仔》)。但三年後,可能由於零件老化(8仔質量問題?),加上近來天氣熱,部8仔又傻傻地(機身很熱),時常錄影不到電視節目,病徵包括錄影不到全個節目(例如一小時節目只錄到半小時),個鐘short左將一還未夠鐘的節目錄低(誤差有成半日),hang機,認不到USB硬碟(但我用硬碟diagnositic工具找不到問題)。

錄影不到節目的結果是被老婆大人投訴,因為不是所有TVB的節目都能在mytv睇得番(可能是網上版權問題),試過真是有次有劇集的大結局不能錄到而不高興。

其實我真有點喜歡8仔的User Interface,所以我有考慮買另一部8仔,但是網上評論真是麻麻。而由於上次2010年ACL經驗(見高清機頂盒轉換記),我也不敢再次其他雜嘜牌子了。但是現在幾乎所有電視機已內置高清解碼器,市場上高清機頂盒的選擇真是不多(反而那些網上播放器就大行其道)。

其實我的要求很簡單,我只是需要一部可同時錄播電影台節目的機頂盒,最好有dual tuner,其他古怪功能就不必。但是質素要隱定,因我覺得時間比金錢寶貴,我不希望我再要因錄影失敗要我花時間上網尋找再download節目(這亦是我不看直播節目的原因,我可以「飛」廣告和遇到不喜歡的錄影便直接delete了事)。

終於我買了Magic TV的3300D(連結


價錢很貴,參考零售價是$1,880。我在格價網最平也要$1,700。這model是不連hard disk的(否則要再貴多一千元!),我在買機是亦被店員揶揄這個價錢連電視機都買得。

現在用了一星期,表現大致滿意:

  • 反應速度okay
  • 同時錄播表現穩定
  • 機身溫度不高
  • 雖然Standby我選用「所有關閉」,但開機速度也算滿意
  • 我特別喜歡它也有8仔的提前開始時間/延長結束時間
  • 而「飛」廣告也可用SKIP掣直接向前跳過30秒(8仔是一分鐘,而廣告時段一定是其倍數)


價錢真是很貴,希望它長命百歲!

2014-04-01

My experience to trouble shoot a notebook computer powering off suddenly


I like programming (hence debugging) but I am not particular interested in trouble-shooting PC installation issues.

A friend of my wife has recently got a second hand notebook PC for his son.  However, the machine will power off randomly, sometimes as early as 1 minute right after power on.  However, if the PC is is booted in Windows Safe mode, the symptom will disappear.

The PC configuration is as follows:

Model: LG R405-A
Operating System: Windows 7 Enterprise
Video card: ATI Radeon Xpress 1250

Why I highlight the Video card because it was also reported there will be AppCrash (about atiundag,dll) when the Powerpoint slideshow mode is activated (and also within Desktop Window Manager (DWM) when the Windows starts).

Therefore my first impression is about the ATI driver version.  However, Windows Update shows it is already running the latest version.

Unbelieving this fact, I go to the ATI web site (now AMD) to download some new version of drivers.  After rebooting, the AppCrash still appears.  Worst still, the random power off problem also still occurs.

However, I notice that right before the powering off, I can hear a sudden increase of the ventilation fan noise.  In fact, from some internet forums, some people has already said that this symptom may be due to overheating.  Then I install some temperature monitoring software and I find that the CPU temperature rises gradually to nearly 100°C and then the machine will shut down.  Then I realize that the previous so called randomness is just due to my testing pattern.  If the machine is off whole night and then power up, then it can sustain longer until the temperature reaches the threshold.  But if I repeatedly reboot the machine and do not wait for it to cool down, of course the temperature problem is not solved and it can reach the threshold within 1 minute after booting up.

At this stage, I still think the ATI driver is the root cause of temperature.  Then I try to go to the LG web site to try to download the ATI driver.  Because Xpress 1250 is a really old chip, in fact, there is no Windows 7 driver for it.  In the LG web site, the latest version is only for Vista.  I did download to try anyway.

To my surprise, the AppCrash problem is solved immediately with the Vista driver.

However, before I can feel happy, the machine turns off again suddenly!

Then I start to think whether there is any hardware issue (e.g. blocked ventilation or bad cooling agent) that causes the high temperature.  I do not want to dismantle the notebook PC.  So, I resort to use the Windows Power Plan to limit the maximum CPU utilization to 50%.  Okay, then the temperature is only around 85°C and does not crash again even though I run YouTube to play video repeatedly.  It seems that the problem is solved (although not fundamentally but at least superficially).

I try to check if there is any fan control utility that can force the fan to always on (I have already setup the BIOS setting but the fan speed is not high).  When I use the SpeedFan software, I notice suddenly that both cores of the CPU is running at 100%.

When I check the task manager, I find that a process dgen.exe is eating my CPU.  It is a virus.  How come I never think about this?  (At a second thought, although the CPU is at 100%, it is not sluggish and still very responsive.)  Afterwards, I update the anti-virus engine and eradicate any other remaining viruses found in the computer.

Postscript: Although the root cause is traced now, I still cannot understand how come the LG computer is so designed that if the CPU keeps on running at 100% loading, the cooling mechanism is not sustainable to keep the temperature within the working limit.

2014-03-04

懷念舅公關傑才先生


在剛過去的農曆新年,和母親提起小時候會去澳門同外祖父母拜年。而且澳門還有一位舅公,他在澳門有一所英語學校,但我年紀小,沒有聽過他說英文,不過他曾送我一本他用中文寫的英文工具書,書名叫《英文解字》,這書的包裝很特別,是一本線裝書!



忽然間有點懷念這一位舅公,但對他的認識不深,只好靠互聯網找找有關他的資料。原本他也編寫過幾本書,其中一本《英譯廣東口語詞典》,在台灣博客來上的作者簡介如下:


關傑才


資深教育工作者,翻譯工作者。先後擔任過中學教務主任;中學高年級英文教師;公開大學特約講師及文字翻譯等職。有豐富的教中國人學英語和教外國人學廣東話的教學經驗。曾編譯出版《英文解字》一書,本書為其又一力作。

而另一編
趙汝能寫給關傑才《詞語疑音字正讀》的序
則見於: http://bbs.qoos.com/viewthread.php?tid=1544660


我在書櫃再找出他送我的《英文解字》線裝書,由於在網上再找不到此書的資料,故我決定將此孤本數碼化,以作紀念!

http://waihungmm.web.fc2.com/english/

另外,下載PDF可於https://drive.google.com/file/d/0Bzo1pJKfp9QELWFKTjlSNUUtZWM/view?usp=sharing



2014-01-22

Detecting errors in jpeg file using libjpeg-turbo

Recently I have the need to detect the integrity of a jpeg file. First I try to see the famous libjpeg (wiki) library can do the job. I am using Visual Studio (i.e. windows) to write my codes and I download the win32 version of libjpeg from internet. However, I keep on failure because the win32 libjpeg library keeps on emitting "Access Violation" at runtime. I try to solve the problem by googling solution but in vain.

Later I turn to use libjpeg-turbo although I really do not need to performance of SIMD instructions. Luckily libjpeg-turbo has a Visual Studio version of static library and I do to encounter the runtime error in libjpeg any more.

Basically my codes should be simply, as illustrated by the following pseudo-codes:

jpeg_create_decompress();
fopen(jpeg_file);
jpeg_stdio_src();
jpeg_read_header();
jpeg_start_decompress();
while loop {
  jpeg_read_scanlines();
  }
jpeg_finish_decompress();
jpeg_destroy_decompress();
fclose();

However, to my surprise, libjpeg use a setjmp/longjmp approach to detect and handle the errors. Frankly speaking, although I have been using C languages for years, I really do not like the GOTO style of handling errors. The libjpeg is emulating an Object-oriented approach by allowing programmer to build an error hander to intercept the errors.

I am interested in two kinds of errors:
  • Fatal errors: the library will quit in this case
  • Warnings: the library can continue with data corruption
The former method is called "error_exit()" and hte latter will invoke "output_message()". So, my job is to build my version of error_exit() and output_message(), with pseudo codes as follows:

my_error_exit ()
{

  /* store the error code in the global variable */
  /* store the error message in the global variable */
  longjmp (myerr->setjmp_buffer, 1); /* Return control to the setjmp point */
}

my_output_message ()
{
  /* store the error code in the global variable */
  /* store the error message in the global variable */
}

The full source listing is as follows:

#include 
#include "stdafx.h"
#include "jpeglib.h"
#include 
#include 

int error_message_code;
char error_message_buffer[JMSG_LENGTH_MAX];

struct my_error_mgr {
  struct jpeg_error_mgr pub;
  jmp_buf setjmp_buffer;
};

typedef struct my_error_mgr * my_error_ptr;

METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  my_error_ptr myerr = (my_error_ptr) cinfo->err;
  error_message_code = cinfo->err->msg_code; /* store the code in the global variable */
  (*cinfo->err->format_message) (cinfo, error_message_buffer);  /* store the message in the global variable */
  printf ("Error intercepted in my_error_exit(): error_code = %d message = \'%s\'\n",
   error_message_code, error_message_buffer);
  longjmp(myerr->setjmp_buffer, 1); /* Return control to the setjmp point */
}

METHODDEF(void)
my_output_message (j_common_ptr cinfo)
{
  error_message_code = cinfo->err->msg_code;
  (*cinfo->err->format_message) (cinfo, error_message_buffer);
}

int _tmain(int argc, _TCHAR* argv[])
{
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr jerr;
  FILE * infile;
  JSAMPARRAY ptr;  /* Output row buffer */
  int row_stride;  /* physical row width in output buffer */

  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  jerr.pub.output_message = my_output_message;
  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp(jerr.setjmp_buffer)) {
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    return 0;
  }

  jpeg_create_decompress(&cinfo);

  if ((infile = fopen("C:\\bin\\libjpeg-turbo\\b.jpg", "rb")) == NULL) {
 printf("cannot open jpeg file");
 return 1;
 }

  jpeg_stdio_src(&cinfo, infile);

  (void) jpeg_read_header(&cinfo, TRUE);

  jpeg_start_decompress(&cinfo);

  row_stride = cinfo.output_width * cinfo.output_components;
  ptr = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,row_stride,1);
 
  while (cinfo.output_scanline < cinfo.output_height) {
    error_message_code = 0;
    jpeg_read_scanlines(&cinfo, (JSAMPARRAY) ptr, 1);
    if (error_message_code) 
       printf("Error occured at scanline %d: Error code = %d message= \'%s\'\n",
         cinfo.output_scanline, error_message_code, error_message_buffer);
    }  // while

  (void) jpeg_finish_decompress(&cinfo);

  jpeg_destroy_decompress(&cinfo);

  fclose (infile);

  return 0;
}

Postscript

I prepare two corrupted jpeg files. The first is truncated file that the exact image height is smaller than that is specified in the jpeg header. In this case, I can successfully intercept the error at scanline 313 with Error code = 120 and error message = "Premature end of JPEG file". The second is truncated that even the jpeg header cannot be successfully read. In this case, my my_error_exit() terminating route can capture the error_code = 51 and error message = "JPEG datastream contains no image".