 Ϣμ˴ؤƹͻ

 ̾դƲ¸
˥塼ƥȤ¸ߤƤƤ٤ʡ

Ĥο̤ȤơβޤȤƤե¸Ȥ
ǽѰդ



 󥯤ȥե(쥹URL)δطϿƤ



 Υͥåȥ顼
㤨http://www9.atwiki.jp/puyopuyokaku/βɤ߹߻ˡ
Pragmra:
ȤΥ쥹ݥ󥹥إå֤ƤΤǡΤǥ顼ˤ
ƤΤ褦ѹƤޤͥ
Ĵ



 äѡϢǥ꥽꡼Ƥ
ۤĥƤ륹򸫤ǥ꥽ܤ˸
ʤΤϥˤ񤵤롣Ƥ֤˾񤵤ƤΤǼǤ
̤ǤϤ뤬ĤƤƤʤ͡
ƱURLǥǡϡɽƱǤ¤ꡢ
줬ۤʤäƤƤ˶ͭ롣ޤä˥ݥåץåɽξǸ
ȯ롢ɽǢɽΤ褦ˤ˥βǽθ
ơºݤɽƤ륹줬ĤƤ⡢30ø
Ǥϲǡ˴Ƥʤơ30øޤǤ˺Ѥʤ
ǡϼºݤ˴Ƥ롣դΥåäƤ櫓
Ϥʤɤ߹߻ʣΥåɤ饢
GdkPixbufLoaderGObjectŪref_countꤷƤ̤˴Ƥ
ΤǡGdkPixbufLoader֥Ȥ꡼Ƥʤ
Ĵ̡ɽŪˤϤΤǤ̵褦ʵƤ
ġġƧǤ
ޤValgrindäˤʤ뤫ġġ



 GdkPixbufLoaderϤäѤꡢthread safeȤޤǤϸʤ(λ)
ΤΤthread safeʷϵGTK+ȤߺѤͤȡ
ϤGDK_THREADS_ENTER()ʴĶǤɬפʾ̤
̯ǤϤ뤬GdkPixbufLoaderνޤGTK+GdkPixbufʤ
GdkPixbufAnimationʤ򸫤ʤɤΤ⤷ʤ
"closed"ʥμ⤷ϡ"closed"ʥθ˼
"area-prepared"⤷"area-updated"ޤǤGdkPixbufLoader
GdkPixbufGdkPixbufAnimationΤˤ褦



 󥯤ؤΥ̤ϿƤ(Ͽ̤ϴλ)
404302ʤɤξ硢ʹߤ⥢˼Ԥ˷ޤäƤ롣
ϡ㽪λޤǼԤεϿ˻ĤȤǼԤURL
ܰʹߤΥǤƤ뤬permanent˵ϿƤ
󡢾ñĴäƤޤΤǡϿ
֥ʤоõȤˤ٤



 åޥ͡
GtkFileChooserDialogGtkImageʥץӥ塼դơ¸
(tenure)褦ˤɤ



 äѡɽϾ¤ɬפ⡩(ûŪ¸̵)
Τ륹ɽƤ顢Υߥ󥰤
Хåȥ졼򸫤¤ꡢGdkPixbufLoaderǥå˲
褦˸롣gif˥ݥåץåɽƤν


ߡɤ⤷ϥå夫ɤGdkPixbufμ̿
GtkImageμ̿˹碌Ƥ뤬̤ˤͤ롣㤨С
map/unmapƻ뤷Ƥɤ߹ߤmapƤΤͥ褷Ʊ
꥽ФGtkImageunmap줿GdkPixbufβθ롣
ߤGtkImageΤ褦timeoutǴƤɤ褽β
򸵤LRUä˴Ȥ⤢롣

GtkScrolledWindowview-port˼ޤäͥŪ˽Ȥ
ϡUIŪˤ˾ޤ롣

âɤϻ֤ݤΤ̤̤ͥˤƤХå饦
ɤǿʤƤ

ˤmap/unmapδƻ뤬ͭյɤΤɬפ롣

map
map-event
unmap
unmap-event
ݤ⤤Ȥwww
map󡢤ƤGtkWidgetˤĤơ餯ǽˡȯԤ줿
Ǥʹ̵߲ˤʤ롣map-eventunmapunmap-eventϸΤǤ
GtkImageʤȤǽϹ⤤ΤƤGtkImage
GtkEventBoxȤΤϥХͽ롣
GtkEventBoxƤ⿶񤤤ܤä

exposeܤäѤꡢȿʤȤʪˤʤʤ

 
μκٹ򤹤Ĥʤ顢GtkTextViewͳOchushaHypertextView
ϤʤμǡġGdkPixbuf꡼ɽƤ
ɤİǤ˻äƤʤ褦



 쥯ȤбˤĤ(SchemeɤΤߡ)

imepitaŪʲåץ(ꤵ줿URLhtmlʸɤ߹ߡ
ϤʤȲΤURLȽ̤Ǥʤ)β⥤饤
ɽʡȹͤȡΤޤޤImageManager¤ƻȤΤϤ
̵ꤲ

 imepitaŪȤ
imepita.jp
*.pic.to
lapislazuli.ath.cx(javascriptȤʤ̵)


 URL񤭴Referer٤ǹԤʥ
www.imgup.org
  http://www.imgup.org/iup722407.jpg.htmlʤ
URLRefererȤhttp://www.imgup.org/iup722407.jpg
ɡ

iyhoo.net
http://iyhoo.net/up/src/up0158.jpg.htmlʤ
URLRefererȤhttp://iyhoo.net/up/src/up0158.jpg
ɡ

kjm.kjr.jp
http://kjm.kir.jp/pc/?p=65918.jpgʤ
URLRefererȤhttp://kjm.kir.jp/pc/img/65918.jpg
ɡ

www.xbitlabs.com
http://www.xbitlabs.com/misc/picture/?src=/images/video/zotac-gfgtx280amp/zotac_power_full.png&1=1
URLRefererȤhttp://www.xbitlabs.com/images/video/zotac-gfgtx280amp/zotac_power_full.png
ɡ

SchemeǤβؿ

 (rewrite-image-link url)ؤ׵ͤѹ褦
ʸ֤줿顢ʸurlȸ
(ʸa . ʸb)
Ȥڥ֤줿顢ʸaredirectURLʸbrefererȸ

Źʾ塢(桼鸫֥֥饦ʤɤϤ)url
񤭴줿URLؤѴΰ٤Υ桼ƥƥؿѰդƤɬ
פ롣ʤȡġϤե뤬ƱǤʤȤˤʤ롣

ImageLoaderInfoλͤ¿ѹredirected_urlϢǤ褦ˤ
Ƥ

redirected_urlǤĤξ硢ؤΥФRefererϸ
urlredirected_urlʣ硢ǿurl衢ĸŤ
ΤRefererȤƼ갷


߷פβǤϡåեɤ⤦Ȥ̵
ʤäƤȤ˼˥ͥåȥؤΥڤؤ
ˡͥåȥɤ߹ǡ̤Ȥƥ쥯
ŪHTMLեäġĤȤˤ⡢쥹ݥ󥹥إåλ
status=200Content-Type: text/html;ä顢Ȥɤ߹Ѥ
ɤ߹߽λʳSchemeؿƤ֤ʤꤷơ쥯
ŬڤURLȽImageLoaderInfo˥쥯Ͽơ
ImageLoaderInfo򥭥塼᤹ŪʼнǤ롣



 ImageManagerloader_queuebusy_queueImageLoaderInfo(ܴۤλ)
ߡenqueuedequeue٤loader_queuebusy_queueӤƤ뤬ͣ
ݾڤ뤿ΤȤʤΤǡ̵̤ʤȤ¿

ʤʤ顢loader_queueäƤǿenqueueΤϡ
饤Τenqueue줿塢줬̤ξ֤ǡƱ꥽
ФݥåץåפΤβ׵ᤵ줿ġĤȤȸä
ɤ¾˹ͤϡƱƱ⤷̥֤Υɽ
ġĤȤΤߡ

Ĥޤꡢ¿ξImageLoaderInfoϣ󤷤enqueueʤˤؤ餺
ܤenqueueǤʤΤϥʤȤ⡢ImageLoaderInfo
塼äƤ롦äƤʤȤ󤬼ޤäƤǡʬ¤
Ȧ



 ޤХäƤ()
ImageLoaderξܤޤäƤʤΤȡʤnotify_error()
ƤʤΤġġ

http://up2.viploader.net/pic3/src/vl2_074519.jpg
ɤ㡣

closedʥ뤬Զ硣



 ե뤬äʤ礬ˤĤ()
եȥĤDuawinĥƤե뤬ɤ߹ߤ
ȤɽƤˤؤ餺ե뤬tmp˻ĤäƤ롣
餯åǤƤʤǤʡ
ˤΤˤΤʤɸ
GdkPixbufLoaderʥȯԤꤷƤΤȤϰۤʤ
礬褦
size_preparedarea_prepared(area_updated)closedˤʤ
ȻפäƤclosed礬͡GdkPixbufLoaderΥ
Ȥ⤹뤬ġġ



 ImageManagerκ߷(λ)

ߤ
GtkWidget *ImageManager::get_widget(const char *url, gint width, gint height);
GtkWidget *urlбɽ륦åȤǤ
APIѤ٤Ǥʤ

ѹݥȤϡߥåե뤫βɤ߹ߤΤߡ
åɿ򣱤Ĥ˸ꤷƤ̤ȤʣβƱɤ߹ޤ
򵯤ʤ褦ˤƤ롣

ͥåȥΥɤξˤ̵¤¿βɤ
⤦Ȥ롣ϻͥХȤ٤ΤʤΤ¤


 ֥Ȥ()
 ImageInfo
URLȤбGdkPixbufLoaderȲΥɤ߹ߤη
GdkPixbufAnimation⤷GdkPixbufơβɽƤ
GtkImageΥꥹȤŻ˴륪֥ȡƱURLƱ
ĤǤɽƤ(ƤGtkImagedestroyޤ)ϡ
ͥåȥ⥭åե뤫ɤ߹̵GtkImage
뤳ȤǤ롣ޤƤGtkImagedestroyƤ⡢äδ(ߤ
30)˻ĤäƤΤǡ㤨вݥåץåפФä
򷫤֤ƤޤäƤ褦ʾˤƤ⡢̵̤ɤ߹ߤ򤱤뤳
ȤǤ롣
URL⤷ϥɥᥤβ򤢤ܡ󤹤ݤˡɽƤޤäƤ
ʬβ̵(ܡ֤ɽGTK_STOCK_DIALOG_WARNINGɽ)
ˤ⡢GtkImageΥꥹȤȤäƤ롣

ġImageInfoˤϰʲΤ褦ʾ֤롣
(1) ɤ߹ߤϤ
(2) ɤ߹ߤϤ줿ɤ߹ǤƤ˲ɤ
Ƚ
(3) ɤ߹ΥǡǤȽɤ߹ߤ̤λ
(4) ɤ߹ߤλ֡
(5) ɤ߹ǡǤʤȽɤ߹ߤ˼Ԥ֡
ߤξΤImageInfoϤ㽪λޤĤꡢƱ
ؤκ٤ΥƤ뤬DBȤäƤ
persistentʾȤƻĤ
(6) ܡ󤵤줿֡
(7) ƤGtkImagedestroy졢ǤޤǤΥॢȤԤľ֡

ߤΤȤ
(1)(2)OCHUSHA_STOCK_MISSING_IMAGE
(3)(4)ɤ߹β
(5)GTK_STOCK_MISSING_IMAGE
(6)GTK_STOCK_DIALOG_WARNING
GtkImageɽƤ뤬CompositeIconȤäơ
(1)OCHUSHA_STOCK_MISSING_IMAGE + OCHUSHA_STOCK_NET_WAIT
(2)OCHUSHA_STOCK_MISSING_IMAGE
 + OCHUSHA_STOCK_NET_PREPARATION/OCHUSHA_STOCK_NET_PROGRESS*
(3)(4)ɤ߹β
(5)GTK_STOCK_MISSING_IMAGE
(6)GTK_STOCK_DIALOG_WARNING
Τ褦ˤ

ŪˤϡImageManagerΥ塼ϿǤϾ(1)ʤΤǡ
OCHUSHA_STOCK_MISSING_IMAGE + OCHUSHA_STOCK_NET_WAIT
ɽƤ

WorkerThread塼ImageInfoФǡ(2)ذܹԤ
Τǡ
OCHUSHA_STOCK_MISSING_IMAGE + OCHUSHA_STOCK_NET_PREPARATION
ɽ롣

ͥåȥξˤϥͥ󤬳Ωǡ
å夫ɤ߹ߤξˤϥåե뤬̵顢
OCHUSHA_STOCK_MISSING_IMAGE + OCHUSHA_STOCK_NET_PROGRESS*
ɽ롣

ǡɤ߹ߤοʹԤˤGdkPixbufLoaderΥʥ뤬ȯԤΤǡ
size_preparedarea_preparedarea_updated˹碌
ɤ߹βΤΤɽ褦ѹ롣줬(3)
롣

ͥåȥｪλ⤷ϥåեɤ߹ߤν
λˤä˲⤹ɬפϤʤ줬(4)

ͥåȥμԡ⤷ϥݡȤǤʤäˤ
GTK_STOCK_MISSING_IMAGEɽ롣줬(5)

ܡ󤵤줿顢GTK_STOCK_DIALOG_WARNINGɽ롣줬(6)



 ImageBuffer
BufferΥ֥饹Ǥꡢappend_data()override뤳Ȥǥͥåȥ
ɤ߹ǡ༡ŪGdkPixbufLoader˽񤭹ࡣƱˡ
Ū˲եǤˤϥå夵եؤν񤭹
ߤԤ

ߤμǤϡåե뤫βɤ߽Фξˤ⤳
ѤƤ뤬¼ʪ̼ˤɤ⤷줺
GdkPixbufLoaderμ갷ϥͥåȥΥɻȥե
뤫ɤ߹߻Ѥʤᡢζʬ򤯤Ф٤
ġġ


 ImageAgentData
NetworkAgentuser_dataȤRefCount׵᤹뤿ᡢRefCount֥
ȤǤϤʤImageManageruser_dataȤͿ뤿ѤƤåѡ
֥ȡ

 LoadImageJob
ߡWorkerJob¹Ԥ륹åɤ򤿤Ĥ¤ġΥ
åɤɬ¸ߤ뤳Ȥݾڤ뤿ThreadPoolImageManager˻
Ƥ뤬ʤʡ

ImageManagerդ˥塼ƤΥ塼򸵤ˣĤĲ
ɤ߹ߤԤ塼ʤMonitorԤĤ褦WorkerJobController
ThreadPoolꤲƺѤޤ٤âȤƽλ˶餯
MonitorԤäƤ륹åɤ˽λ¥ɬפ롣

塼ȤȤˤꡢɤ߹ߤ̵̤︺Ǥǽ롣
塼Ф׵(ImageInfo֥ȡ)ˤĤơ(줬
줿ʤɤη)λǴطGtkImage¸ߤʤСɤ߹
ߤ¹ԤɬפϤʤʤ롣ä˥åե뤫ɤ߹ߤϴ
פȤʤ뤷(åեtouchϤƤ٤)ͥå
ɤ߹ߤߤƤޤäɤ(ɤ߹ߤͤ⤤뤫
ʤΤǡդprefsǡġ)

WorkerJobϡĤImageLoaderInfoФ٤˥塼Ƭ
龨!busyĥå¸ߤΤ֡Ƭ鸫
Τinteractiveե饰դǤenqueue()б뤿ᡣå̵
ʬˤĤƤϡͥåȥȼɤ߹ߤΤ(Ʊ
߹߿nĤ˸ꤹ)ޥեߤ⤢Τǡ̤Τäǽ
Ϥ롣

busyե饰פ褦ʵ⤹ʡ
ImageManagerνǥ塼äƤImageLoaderInfoν򳫻Ϥġ
Ȥäʬϡ٤ˡ¾椵ƤΤǰäơ
γϤȽλˡֽꥹȡפ򹹿뤳ȤImageLoaderInfo
ξ֤İǤ롣ImageManager::enqueue(info)줿infoֽ
ꥹȡ¸ߤ顢queueɬפϤʤޤ
äǡImageLoaderInfopending_loader_listǤʤС
˿׵᤬äȤ̣Τǿqueue뤫ͥ
Ūˤɤ



 ̤β󥯤ȤʻˤʤˤĤ()
(1) mkstemp()μԤTmpfileNULLˤʤꡢSegmentation Fault
ѡ
(2) Τ̤ΥͥƱĥ롣
¤ˤ뤫⡣
⤽쵤ȤΤϻߤ٤⡣
ImageManagerǥꥢ饤ơƱȤΤϺNޤǡġ
Ȥ褦ʼѤ٤ĤǤˡimepitaŪȸ
URLٱ񤭴ˡȤ߹ߤ



 ܡ()
ߤplain textʵϿեURLʸʸ󼫿ȤȤϥåơ
֥ǴƤ뤬SQLite3ޤˤ褦ͭʤۤ
粽Ƥ¿ʵ뤷



