TECH 으로 돌아가기
TECH HACKER NEWS 오늘 7분 읽기 45 READS

전자책 리더기를 프린터로: IPP로 만든 '무드라이버' 출력 실험

전자책 리더기를 프린터로: IPP로 만든 '무드라이버' 출력 실험
SOURCE IMAGE · HACKER NEWS

전자잉크(e-ink) 화면은 종이를 닮았다. 그렇다면 종이처럼 '인쇄'할 수 있어야 하지 않을까. 한 개발자가 프로그래밍이 가능하다고 소개된 Xteink X3라는 전자책 리더기를 손에 넣은 뒤, 이를 실제 프린터처럼 동작하게 만든 과정을 정리한 글이 흥미로운 이유가 여기에 있다. 원래는 전자잉크 디스플레이를 직접 만들려던 계획이었지만, '완전히 프로그래밍 가능(fully programmable)'이라는 제품 설명 문구가 방향을 바꿔놓았다. 그는 기기의 CrossPoint 펌웨어에 부팅 애니메이션을 교체하고, 흔들면 주사위가 굴러가는 기능이나 네트워킹 행사용 링크드인 QR 코드를 추가하며 실험을 시작했다.

문제는 기기에 콘텐츠를 넣는 방식이 번거로웠다는 점이다. 리더기가 만든 핫스팟에 접속해 브라우저에서 업로드 페이지를 여는 과정을 매번 반복해야 했다. 그래서 그는 맥북에서 문서를 열고 '인쇄' 버튼을 누른 뒤 목록에서 이 기기를 고르는, 진짜 프린터 같은 경험을 목표로 삼았다. 이를 위해서는 컴퓨터가 프린터 쪽에서 무엇을 기대하는지부터 알아야 했다.

IPP라는 공용 언어

답은 인터넷 인쇄 프로토콜(IPP, Internet Printing Protocol)에 있었다. IPP는 컴퓨터가 프린터에게 어떤 기능을 지원하는지 묻고, 문서를 제출하고, 작업 결과를 확인할 수 있게 해주는 표준이다. 메시지는 HTTP 위에서 오간다. 예를 들어 Get-Printer-Attributes 연산은 프린터의 성능을 묻고, Print-Job 연산은 실제 인쇄 작업을 전달한다. 개발자는 이 기기를 흑백 출력, 300dpi, 1부, 단면 인쇄를 지원하는 장치로 광고했다. 문서 형식으로는 애플 래스터와 PWG 래스터를 받아들이도록 설정했는데, 이는 맥이 문서를 미리 픽셀로 변환해 보낸다는 뜻이고 기기 쪽에서는 그 결과를 화면 크기에 맞게 줄이기만 하면 된다. 용지는 A5와 레터, 용지 종류는 stationery, 출력함 이름은 face-up으로 선언했다.

기기를 네트워크상에 노출하는 데는 Bonjour를 썼다. '펭귄(penguin)'이라는 이름으로 _ipp._tcp 서비스를 알렸고, 광고에는 받아들일 수 있는 형식과 인쇄 작업을 보낼 주소를 함께 담았다. 다만 macOS의 드라이버 없는(driverless) 자동 검색이 작동하게 하려면 _universal 하위 유형을 추가해야 했는데, 아두이노 래퍼가 이 기능을 노출하지 않아 ESP-IDF의 mDNS API를 직접 호출해야 했다. 표준을 흉내 내는 일이 종종 이런 저수준 우회를 요구한다는 점을 보여주는 대목이다.

400KB 램으로 한 장을 받는 법

진짜 난관은 메모리였다. 300dpi 레터 한 장은 2,550×3,300픽셀, 그레이스케일 기준 픽셀당 1바이트로 계산하면 압축하지 않은 상태에서 약 8.4MB에 이른다. 그런데 X3의 램은 400KB에 불과하고 그중 16KB는 캐시로 예약돼 있다. 여기서 와이파이와 프린터 서버를 동시에 돌리고 페이지까지 받아야 했다. 와이파이를 켜고 페이지 이미지를 할당하고 나니 남은 힙 메모리는 6.8KB뿐이었다.

해법은 발상의 전환이었다. 페이지 전체를 메모리에 모았다가 화면으로 복사하는 대신, 들어오는 데이터를 곧바로 디스플레이의 화면 버퍼에 그려 넣는 것이다. 디스플레이는 이미 자기 화면 이미지를 위한 램을 갖고 있으니, 그 공간을 최종 결과물을 조립하는 자리로 삼았다. 픽셀을 디코딩하고, 화면에 맞게 축소하고, 흑백으로 디더링한 뒤, 한 줄이 완성될 때마다 제자리에 배치하고 작업 공간을 재사용하는 파이프라인이다. 기존 디코더가 이미 한 줄씩 처리하고 있었기에, 스케일러도 완성된 줄을 넘겨주도록 바꿔 디스플레이 버퍼에 연결했다. 처음에는 종이가 프린터에서 밀려 나오듯 페이지가 띠 모양으로 나타나게 했지만, 중간 갱신마다 약 0.5초가 걸려 결국 완성된 페이지를 한 번에 보여주는 방식으로 바꿨다. 완성된 페이지는 기존 스크린샷 저장 기능을 활용해 SD 카드에 BMP로 저장했고, 그 덕에 네트워크 스택이 소켓 버퍼를 쓸 여유도 확보됐다.

결과는 성공적이었다. 맥북에 있던 만화 이미지를 미리보기로 열어 인쇄를 누르자, 약 1초 만에 화면에 또렷하게 나타났다고 한다. 저녁 한나절 만에 첫 출력에 도달한 셈이다. 프린터 서버는 리더기 자체에서 돌아가며, 기존 와이파이에 접속하거나 자체 핫스팟을 띄우는 두 방식을 모두 지원한다. 저장된 출력물은 SD 카드에 남아 기기에서 다시 열어볼 수 있는데, 개발자는 이 폴더를 두고 '내 프린터에도 결국 출력함이 있는 셈'이라고 표현했다.

한국 IT 실무자 입장에서 이 실험이 주는 함의는 단순한 취미 이상의 것이다. 첫째, IPP와 Bonjour/mDNS 같은 개방형 표준을 흉내 내는 것만으로 임의의 장치를 운영체제의 기본 인쇄 흐름에 자연스럽게 끼워 넣을 수 있다는 점이다. 별도의 앱이나 드라이버 배포 없이 '인쇄' 버튼 하나로 연동되는 사용자 경험은 사물인터넷 기기 설계에 참고할 만하다. 둘째, 6.8KB만 남은 극한의 임베디드 환경에서 전체 버퍼링을 포기하고 스트리밍 파이프라인으로 문제를 재정의한 접근은, 자원 제약을 우회하기보다 데이터 흐름 자체를 바꾸는 최적화의 전형을 보여준다. 다만 이 결과물은 검증된 제품이 아니라 한 사람이 자신의 기기에서 확인한 실험이라는 한계도 분명하다. 흑백 300dpi 래스터 이미지 출력이라는 좁은 시나리오에 맞춰져 있고, 다양한 문서 형식이나 안정성·보안에 대한 검증은 원문에 언급되지 않았다. 그럼에도 '종이처럼 보이면 종이처럼 굴어야 한다'는 발상을 표준 프로토콜과 저수준 최적화로 밀어붙인 과정 자체가, 기존 하드웨어의 용도를 다시 상상하는 좋은 사례로 남는다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://nishantjosh.dev/blogs/how-to-build-a-fking-printer/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...